wl_proxy/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 crate::protocol_helpers::prelude::*;
47use super::super::all_types::*;
48
49/// A wl_surface object.
50///
51/// See the documentation of [the module][self] for the interface description.
52pub struct WlSurface {
53    core: ObjectCore,
54    handler: HandlerHolder<dyn WlSurfaceHandler>,
55}
56
57struct DefaultHandler;
58
59impl WlSurfaceHandler for DefaultHandler { }
60
61impl ConcreteObject for WlSurface {
62    const XML_VERSION: u32 = 6;
63    const INTERFACE: ObjectInterface = ObjectInterface::WlSurface;
64    const INTERFACE_NAME: &str = "wl_surface";
65}
66
67impl WlSurface {
68    /// Sets a new handler.
69    pub fn set_handler(&self, handler: impl WlSurfaceHandler) {
70        self.set_boxed_handler(Box::new(handler));
71    }
72
73    /// Sets a new, already boxed handler.
74    pub fn set_boxed_handler(&self, handler: Box<dyn WlSurfaceHandler>) {
75        if self.core.state.destroyed.get() {
76            return;
77        }
78        self.handler.set(Some(handler));
79    }
80}
81
82impl Debug for WlSurface {
83    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
84        f.debug_struct("WlSurface")
85            .field("server_obj_id", &self.core.server_obj_id.get())
86            .field("client_id", &self.core.client_id.get())
87            .field("client_obj_id", &self.core.client_obj_id.get())
88            .finish()
89    }
90}
91
92impl WlSurface {
93    /// Since when the destroy message is available.
94    pub const MSG__DESTROY__SINCE: u32 = 1;
95
96    /// delete surface
97    ///
98    /// Deletes the surface and invalidates its object ID.
99    #[inline]
100    pub fn try_send_destroy(
101        &self,
102    ) -> Result<(), ObjectError> {
103        let core = self.core();
104        let Some(id) = core.server_obj_id.get() else {
105            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
106        };
107        #[cfg(feature = "logging")]
108        if self.core.state.log {
109            #[cold]
110            fn log(state: &State, id: u32) {
111                let (millis, micros) = time_since_epoch();
112                let prefix = &state.log_prefix;
113                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.destroy()\n", id);
114                state.log(args);
115            }
116            log(&self.core.state, id);
117        }
118        let Some(endpoint) = &self.core.state.server else {
119            return Ok(());
120        };
121        if !endpoint.flush_queued.replace(true) {
122            self.core.state.add_flushable_endpoint(endpoint, None);
123        }
124        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
125        let outgoing = &mut *outgoing_ref;
126        let mut fmt = outgoing.formatter();
127        fmt.words([
128            id,
129            0,
130        ]);
131        self.core.handle_server_destroy();
132        Ok(())
133    }
134
135    /// delete surface
136    ///
137    /// Deletes the surface and invalidates its object ID.
138    #[inline]
139    pub fn send_destroy(
140        &self,
141    ) {
142        let res = self.try_send_destroy(
143        );
144        if let Err(e) = res {
145            log_send("wl_surface.destroy", &e);
146        }
147    }
148
149    /// Since when the attach message is available.
150    pub const MSG__ATTACH__SINCE: u32 = 1;
151
152    /// set the surface contents
153    ///
154    /// Set a buffer as the content of this surface.
155    ///
156    /// The new size of the surface is calculated based on the buffer
157    /// size transformed by the inverse buffer_transform and the
158    /// inverse buffer_scale. This means that at commit time the supplied
159    /// buffer size must be an integer multiple of the buffer_scale. If
160    /// that's not the case, an invalid_size error is sent.
161    ///
162    /// The x and y arguments specify the location of the new pending
163    /// buffer's upper left corner, relative to the current buffer's upper
164    /// left corner, in surface-local coordinates. In other words, the
165    /// x and y, combined with the new surface size define in which
166    /// directions the surface's size changes. Setting anything other than 0
167    /// as x and y arguments is discouraged, and should instead be replaced
168    /// with using the separate wl_surface.offset request.
169    ///
170    /// When the bound wl_surface version is 5 or higher, passing any
171    /// non-zero x or y is a protocol violation, and will result in an
172    /// 'invalid_offset' error being raised. The x and y arguments are ignored
173    /// and do not change the pending state. To achieve equivalent semantics,
174    /// use wl_surface.offset.
175    ///
176    /// Surface contents are double-buffered state, see wl_surface.commit.
177    ///
178    /// The initial surface contents are void; there is no content.
179    /// wl_surface.attach assigns the given wl_buffer as the pending
180    /// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
181    /// surface contents, and the size of the surface becomes the size
182    /// calculated from the wl_buffer, as described above. After commit,
183    /// there is no pending buffer until the next attach.
184    ///
185    /// Committing a pending wl_buffer allows the compositor to read the
186    /// pixels in the wl_buffer. The compositor may access the pixels at
187    /// any time after the wl_surface.commit request. When the compositor
188    /// will not access the pixels anymore, it will send the
189    /// wl_buffer.release event. Only after receiving wl_buffer.release,
190    /// the client may reuse the wl_buffer. A wl_buffer that has been
191    /// attached and then replaced by another attach instead of committed
192    /// will not receive a release event, and is not used by the
193    /// compositor.
194    ///
195    /// If a pending wl_buffer has been committed to more than one wl_surface,
196    /// the delivery of wl_buffer.release events becomes undefined. A well
197    /// behaved client should not rely on wl_buffer.release events in this
198    /// case. Alternatively, a client could create multiple wl_buffer objects
199    /// from the same backing storage or use a protocol extension providing
200    /// per-commit release notifications.
201    ///
202    /// Destroying the wl_buffer after wl_buffer.release does not change
203    /// the surface contents. Destroying the wl_buffer before wl_buffer.release
204    /// is allowed as long as the underlying buffer storage isn't re-used (this
205    /// can happen e.g. on client process termination). However, if the client
206    /// destroys the wl_buffer before receiving the wl_buffer.release event and
207    /// mutates the underlying buffer storage, the surface contents become
208    /// undefined immediately.
209    ///
210    /// If wl_surface.attach is sent with a NULL wl_buffer, the
211    /// following wl_surface.commit will remove the surface content.
212    ///
213    /// If a pending wl_buffer has been destroyed, the result is not specified.
214    /// Many compositors are known to remove the surface content on the following
215    /// wl_surface.commit, but this behaviour is not universal. Clients seeking to
216    /// maximise compatibility should not destroy pending buffers and should
217    /// ensure that they explicitly remove content from surfaces, even after
218    /// destroying buffers.
219    ///
220    /// # Arguments
221    ///
222    /// - `buffer`: buffer of surface contents
223    /// - `x`: surface-local x coordinate
224    /// - `y`: surface-local y coordinate
225    #[inline]
226    pub fn try_send_attach(
227        &self,
228        buffer: Option<&Rc<WlBuffer>>,
229        x: i32,
230        y: i32,
231    ) -> Result<(), ObjectError> {
232        let (
233            arg0,
234            arg1,
235            arg2,
236        ) = (
237            buffer,
238            x,
239            y,
240        );
241        let arg0 = arg0.map(|a| a.core());
242        let core = self.core();
243        let Some(id) = core.server_obj_id.get() else {
244            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
245        };
246        let arg0_id = match arg0 {
247            None => 0,
248            Some(arg0) => match arg0.server_obj_id.get() {
249                None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("buffer"))),
250                Some(id) => id,
251            },
252        };
253        #[cfg(feature = "logging")]
254        if self.core.state.log {
255            #[cold]
256            fn log(state: &State, id: u32, arg0: u32, arg1: i32, arg2: i32) {
257                let (millis, micros) = time_since_epoch();
258                let prefix = &state.log_prefix;
259                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.attach(buffer: wl_buffer#{}, x: {}, y: {})\n", id, arg0, arg1, arg2);
260                state.log(args);
261            }
262            log(&self.core.state, id, arg0_id, arg1, arg2);
263        }
264        let Some(endpoint) = &self.core.state.server else {
265            return Ok(());
266        };
267        if !endpoint.flush_queued.replace(true) {
268            self.core.state.add_flushable_endpoint(endpoint, None);
269        }
270        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
271        let outgoing = &mut *outgoing_ref;
272        let mut fmt = outgoing.formatter();
273        fmt.words([
274            id,
275            1,
276            arg0_id,
277            arg1 as u32,
278            arg2 as u32,
279        ]);
280        Ok(())
281    }
282
283    /// set the surface contents
284    ///
285    /// Set a buffer as the content of this surface.
286    ///
287    /// The new size of the surface is calculated based on the buffer
288    /// size transformed by the inverse buffer_transform and the
289    /// inverse buffer_scale. This means that at commit time the supplied
290    /// buffer size must be an integer multiple of the buffer_scale. If
291    /// that's not the case, an invalid_size error is sent.
292    ///
293    /// The x and y arguments specify the location of the new pending
294    /// buffer's upper left corner, relative to the current buffer's upper
295    /// left corner, in surface-local coordinates. In other words, the
296    /// x and y, combined with the new surface size define in which
297    /// directions the surface's size changes. Setting anything other than 0
298    /// as x and y arguments is discouraged, and should instead be replaced
299    /// with using the separate wl_surface.offset request.
300    ///
301    /// When the bound wl_surface version is 5 or higher, passing any
302    /// non-zero x or y is a protocol violation, and will result in an
303    /// 'invalid_offset' error being raised. The x and y arguments are ignored
304    /// and do not change the pending state. To achieve equivalent semantics,
305    /// use wl_surface.offset.
306    ///
307    /// Surface contents are double-buffered state, see wl_surface.commit.
308    ///
309    /// The initial surface contents are void; there is no content.
310    /// wl_surface.attach assigns the given wl_buffer as the pending
311    /// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
312    /// surface contents, and the size of the surface becomes the size
313    /// calculated from the wl_buffer, as described above. After commit,
314    /// there is no pending buffer until the next attach.
315    ///
316    /// Committing a pending wl_buffer allows the compositor to read the
317    /// pixels in the wl_buffer. The compositor may access the pixels at
318    /// any time after the wl_surface.commit request. When the compositor
319    /// will not access the pixels anymore, it will send the
320    /// wl_buffer.release event. Only after receiving wl_buffer.release,
321    /// the client may reuse the wl_buffer. A wl_buffer that has been
322    /// attached and then replaced by another attach instead of committed
323    /// will not receive a release event, and is not used by the
324    /// compositor.
325    ///
326    /// If a pending wl_buffer has been committed to more than one wl_surface,
327    /// the delivery of wl_buffer.release events becomes undefined. A well
328    /// behaved client should not rely on wl_buffer.release events in this
329    /// case. Alternatively, a client could create multiple wl_buffer objects
330    /// from the same backing storage or use a protocol extension providing
331    /// per-commit release notifications.
332    ///
333    /// Destroying the wl_buffer after wl_buffer.release does not change
334    /// the surface contents. Destroying the wl_buffer before wl_buffer.release
335    /// is allowed as long as the underlying buffer storage isn't re-used (this
336    /// can happen e.g. on client process termination). However, if the client
337    /// destroys the wl_buffer before receiving the wl_buffer.release event and
338    /// mutates the underlying buffer storage, the surface contents become
339    /// undefined immediately.
340    ///
341    /// If wl_surface.attach is sent with a NULL wl_buffer, the
342    /// following wl_surface.commit will remove the surface content.
343    ///
344    /// If a pending wl_buffer has been destroyed, the result is not specified.
345    /// Many compositors are known to remove the surface content on the following
346    /// wl_surface.commit, but this behaviour is not universal. Clients seeking to
347    /// maximise compatibility should not destroy pending buffers and should
348    /// ensure that they explicitly remove content from surfaces, even after
349    /// destroying buffers.
350    ///
351    /// # Arguments
352    ///
353    /// - `buffer`: buffer of surface contents
354    /// - `x`: surface-local x coordinate
355    /// - `y`: surface-local y coordinate
356    #[inline]
357    pub fn send_attach(
358        &self,
359        buffer: Option<&Rc<WlBuffer>>,
360        x: i32,
361        y: i32,
362    ) {
363        let res = self.try_send_attach(
364            buffer,
365            x,
366            y,
367        );
368        if let Err(e) = res {
369            log_send("wl_surface.attach", &e);
370        }
371    }
372
373    /// Since when the damage message is available.
374    pub const MSG__DAMAGE__SINCE: u32 = 1;
375
376    /// mark part of the surface damaged
377    ///
378    /// This request is used to describe the regions where the pending
379    /// buffer is different from the current surface contents, and where
380    /// the surface therefore needs to be repainted. The compositor
381    /// ignores the parts of the damage that fall outside of the surface.
382    ///
383    /// Damage is double-buffered state, see wl_surface.commit.
384    ///
385    /// The damage rectangle is specified in surface-local coordinates,
386    /// where x and y specify the upper left corner of the damage rectangle.
387    ///
388    /// The initial value for pending damage is empty: no damage.
389    /// wl_surface.damage adds pending damage: the new pending damage
390    /// is the union of old pending damage and the given rectangle.
391    ///
392    /// wl_surface.commit assigns pending damage as the current damage,
393    /// and clears pending damage. The server will clear the current
394    /// damage as it repaints the surface.
395    ///
396    /// Note! New clients should not use this request. Instead damage can be
397    /// posted with wl_surface.damage_buffer which uses buffer coordinates
398    /// instead of surface coordinates.
399    ///
400    /// # Arguments
401    ///
402    /// - `x`: surface-local x coordinate
403    /// - `y`: surface-local y coordinate
404    /// - `width`: width of damage rectangle
405    /// - `height`: height of damage rectangle
406    #[inline]
407    pub fn try_send_damage(
408        &self,
409        x: i32,
410        y: i32,
411        width: i32,
412        height: i32,
413    ) -> Result<(), ObjectError> {
414        let (
415            arg0,
416            arg1,
417            arg2,
418            arg3,
419        ) = (
420            x,
421            y,
422            width,
423            height,
424        );
425        let core = self.core();
426        let Some(id) = core.server_obj_id.get() else {
427            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
428        };
429        #[cfg(feature = "logging")]
430        if self.core.state.log {
431            #[cold]
432            fn log(state: &State, id: u32, arg0: i32, arg1: i32, arg2: i32, arg3: i32) {
433                let (millis, micros) = time_since_epoch();
434                let prefix = &state.log_prefix;
435                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.damage(x: {}, y: {}, width: {}, height: {})\n", id, arg0, arg1, arg2, arg3);
436                state.log(args);
437            }
438            log(&self.core.state, id, arg0, arg1, arg2, arg3);
439        }
440        let Some(endpoint) = &self.core.state.server else {
441            return Ok(());
442        };
443        if !endpoint.flush_queued.replace(true) {
444            self.core.state.add_flushable_endpoint(endpoint, None);
445        }
446        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
447        let outgoing = &mut *outgoing_ref;
448        let mut fmt = outgoing.formatter();
449        fmt.words([
450            id,
451            2,
452            arg0 as u32,
453            arg1 as u32,
454            arg2 as u32,
455            arg3 as u32,
456        ]);
457        Ok(())
458    }
459
460    /// mark part of the surface damaged
461    ///
462    /// This request is used to describe the regions where the pending
463    /// buffer is different from the current surface contents, and where
464    /// the surface therefore needs to be repainted. The compositor
465    /// ignores the parts of the damage that fall outside of the surface.
466    ///
467    /// Damage is double-buffered state, see wl_surface.commit.
468    ///
469    /// The damage rectangle is specified in surface-local coordinates,
470    /// where x and y specify the upper left corner of the damage rectangle.
471    ///
472    /// The initial value for pending damage is empty: no damage.
473    /// wl_surface.damage adds pending damage: the new pending damage
474    /// is the union of old pending damage and the given rectangle.
475    ///
476    /// wl_surface.commit assigns pending damage as the current damage,
477    /// and clears pending damage. The server will clear the current
478    /// damage as it repaints the surface.
479    ///
480    /// Note! New clients should not use this request. Instead damage can be
481    /// posted with wl_surface.damage_buffer which uses buffer coordinates
482    /// instead of surface coordinates.
483    ///
484    /// # Arguments
485    ///
486    /// - `x`: surface-local x coordinate
487    /// - `y`: surface-local y coordinate
488    /// - `width`: width of damage rectangle
489    /// - `height`: height of damage rectangle
490    #[inline]
491    pub fn send_damage(
492        &self,
493        x: i32,
494        y: i32,
495        width: i32,
496        height: i32,
497    ) {
498        let res = self.try_send_damage(
499            x,
500            y,
501            width,
502            height,
503        );
504        if let Err(e) = res {
505            log_send("wl_surface.damage", &e);
506        }
507    }
508
509    /// Since when the frame message is available.
510    pub const MSG__FRAME__SINCE: u32 = 1;
511
512    /// request a frame throttling hint
513    ///
514    /// Request a notification when it is a good time to start drawing a new
515    /// frame, by creating a frame callback. This is useful for throttling
516    /// redrawing operations, and driving animations.
517    ///
518    /// When a client is animating on a wl_surface, it can use the 'frame'
519    /// request to get notified when it is a good time to draw and commit the
520    /// next frame of animation. If the client commits an update earlier than
521    /// that, it is likely that some updates will not make it to the display,
522    /// and the client is wasting resources by drawing too often.
523    ///
524    /// The frame request will take effect on the next wl_surface.commit.
525    /// The notification will only be posted for one frame unless
526    /// requested again. For a wl_surface, the notifications are posted in
527    /// the order the frame requests were committed.
528    ///
529    /// The server must send the notifications so that a client
530    /// will not send excessive updates, while still allowing
531    /// the highest possible update rate for clients that wait for the reply
532    /// before drawing again. The server should give some time for the client
533    /// to draw and commit after sending the frame callback events to let it
534    /// hit the next output refresh.
535    ///
536    /// A server should avoid signaling the frame callbacks if the
537    /// surface is not visible in any way, e.g. the surface is off-screen,
538    /// or completely obscured by other opaque surfaces.
539    ///
540    /// The object returned by this request will be destroyed by the
541    /// compositor after the callback is fired and as such the client must not
542    /// attempt to use it after that point.
543    ///
544    /// The callback_data passed in the callback is the current time, in
545    /// milliseconds, with an undefined base.
546    ///
547    /// # Arguments
548    ///
549    /// - `callback`: callback object for the frame request
550    #[inline]
551    pub fn try_send_frame(
552        &self,
553        callback: &Rc<WlCallback>,
554    ) -> Result<(), ObjectError> {
555        let (
556            arg0,
557        ) = (
558            callback,
559        );
560        let arg0_obj = arg0;
561        let arg0 = arg0_obj.core();
562        let core = self.core();
563        let Some(id) = core.server_obj_id.get() else {
564            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
565        };
566        arg0.generate_server_id(arg0_obj.clone())
567            .map_err(|e| ObjectError(ObjectErrorKind::GenerateServerId("callback", e)))?;
568        let arg0_id = arg0.server_obj_id.get().unwrap_or(0);
569        #[cfg(feature = "logging")]
570        if self.core.state.log {
571            #[cold]
572            fn log(state: &State, id: u32, arg0: u32) {
573                let (millis, micros) = time_since_epoch();
574                let prefix = &state.log_prefix;
575                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.frame(callback: wl_callback#{})\n", id, arg0);
576                state.log(args);
577            }
578            log(&self.core.state, id, arg0_id);
579        }
580        let Some(endpoint) = &self.core.state.server else {
581            return Ok(());
582        };
583        if !endpoint.flush_queued.replace(true) {
584            self.core.state.add_flushable_endpoint(endpoint, None);
585        }
586        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
587        let outgoing = &mut *outgoing_ref;
588        let mut fmt = outgoing.formatter();
589        fmt.words([
590            id,
591            3,
592            arg0_id,
593        ]);
594        Ok(())
595    }
596
597    /// request a frame throttling hint
598    ///
599    /// Request a notification when it is a good time to start drawing a new
600    /// frame, by creating a frame callback. This is useful for throttling
601    /// redrawing operations, and driving animations.
602    ///
603    /// When a client is animating on a wl_surface, it can use the 'frame'
604    /// request to get notified when it is a good time to draw and commit the
605    /// next frame of animation. If the client commits an update earlier than
606    /// that, it is likely that some updates will not make it to the display,
607    /// and the client is wasting resources by drawing too often.
608    ///
609    /// The frame request will take effect on the next wl_surface.commit.
610    /// The notification will only be posted for one frame unless
611    /// requested again. For a wl_surface, the notifications are posted in
612    /// the order the frame requests were committed.
613    ///
614    /// The server must send the notifications so that a client
615    /// will not send excessive updates, while still allowing
616    /// the highest possible update rate for clients that wait for the reply
617    /// before drawing again. The server should give some time for the client
618    /// to draw and commit after sending the frame callback events to let it
619    /// hit the next output refresh.
620    ///
621    /// A server should avoid signaling the frame callbacks if the
622    /// surface is not visible in any way, e.g. the surface is off-screen,
623    /// or completely obscured by other opaque surfaces.
624    ///
625    /// The object returned by this request will be destroyed by the
626    /// compositor after the callback is fired and as such the client must not
627    /// attempt to use it after that point.
628    ///
629    /// The callback_data passed in the callback is the current time, in
630    /// milliseconds, with an undefined base.
631    ///
632    /// # Arguments
633    ///
634    /// - `callback`: callback object for the frame request
635    #[inline]
636    pub fn send_frame(
637        &self,
638        callback: &Rc<WlCallback>,
639    ) {
640        let res = self.try_send_frame(
641            callback,
642        );
643        if let Err(e) = res {
644            log_send("wl_surface.frame", &e);
645        }
646    }
647
648    /// request a frame throttling hint
649    ///
650    /// Request a notification when it is a good time to start drawing a new
651    /// frame, by creating a frame callback. This is useful for throttling
652    /// redrawing operations, and driving animations.
653    ///
654    /// When a client is animating on a wl_surface, it can use the 'frame'
655    /// request to get notified when it is a good time to draw and commit the
656    /// next frame of animation. If the client commits an update earlier than
657    /// that, it is likely that some updates will not make it to the display,
658    /// and the client is wasting resources by drawing too often.
659    ///
660    /// The frame request will take effect on the next wl_surface.commit.
661    /// The notification will only be posted for one frame unless
662    /// requested again. For a wl_surface, the notifications are posted in
663    /// the order the frame requests were committed.
664    ///
665    /// The server must send the notifications so that a client
666    /// will not send excessive updates, while still allowing
667    /// the highest possible update rate for clients that wait for the reply
668    /// before drawing again. The server should give some time for the client
669    /// to draw and commit after sending the frame callback events to let it
670    /// hit the next output refresh.
671    ///
672    /// A server should avoid signaling the frame callbacks if the
673    /// surface is not visible in any way, e.g. the surface is off-screen,
674    /// or completely obscured by other opaque surfaces.
675    ///
676    /// The object returned by this request will be destroyed by the
677    /// compositor after the callback is fired and as such the client must not
678    /// attempt to use it after that point.
679    ///
680    /// The callback_data passed in the callback is the current time, in
681    /// milliseconds, with an undefined base.
682    #[inline]
683    pub fn new_try_send_frame(
684        &self,
685    ) -> Result<Rc<WlCallback>, ObjectError> {
686        let callback = self.core.create_child();
687        self.try_send_frame(
688            &callback,
689        )?;
690        Ok(callback)
691    }
692
693    /// request a frame throttling hint
694    ///
695    /// Request a notification when it is a good time to start drawing a new
696    /// frame, by creating a frame callback. This is useful for throttling
697    /// redrawing operations, and driving animations.
698    ///
699    /// When a client is animating on a wl_surface, it can use the 'frame'
700    /// request to get notified when it is a good time to draw and commit the
701    /// next frame of animation. If the client commits an update earlier than
702    /// that, it is likely that some updates will not make it to the display,
703    /// and the client is wasting resources by drawing too often.
704    ///
705    /// The frame request will take effect on the next wl_surface.commit.
706    /// The notification will only be posted for one frame unless
707    /// requested again. For a wl_surface, the notifications are posted in
708    /// the order the frame requests were committed.
709    ///
710    /// The server must send the notifications so that a client
711    /// will not send excessive updates, while still allowing
712    /// the highest possible update rate for clients that wait for the reply
713    /// before drawing again. The server should give some time for the client
714    /// to draw and commit after sending the frame callback events to let it
715    /// hit the next output refresh.
716    ///
717    /// A server should avoid signaling the frame callbacks if the
718    /// surface is not visible in any way, e.g. the surface is off-screen,
719    /// or completely obscured by other opaque surfaces.
720    ///
721    /// The object returned by this request will be destroyed by the
722    /// compositor after the callback is fired and as such the client must not
723    /// attempt to use it after that point.
724    ///
725    /// The callback_data passed in the callback is the current time, in
726    /// milliseconds, with an undefined base.
727    #[inline]
728    pub fn new_send_frame(
729        &self,
730    ) -> Rc<WlCallback> {
731        let callback = self.core.create_child();
732        self.send_frame(
733            &callback,
734        );
735        callback
736    }
737
738    /// Since when the set_opaque_region message is available.
739    pub const MSG__SET_OPAQUE_REGION__SINCE: u32 = 1;
740
741    /// set opaque region
742    ///
743    /// This request sets the region of the surface that contains
744    /// opaque content.
745    ///
746    /// The opaque region is an optimization hint for the compositor
747    /// that lets it optimize the redrawing of content behind opaque
748    /// regions.  Setting an opaque region is not required for correct
749    /// behaviour, but marking transparent content as opaque will result
750    /// in repaint artifacts.
751    ///
752    /// The opaque region is specified in surface-local coordinates.
753    ///
754    /// The compositor ignores the parts of the opaque region that fall
755    /// outside of the surface.
756    ///
757    /// Opaque region is double-buffered state, see wl_surface.commit.
758    ///
759    /// wl_surface.set_opaque_region changes the pending opaque region.
760    /// wl_surface.commit copies the pending region to the current region.
761    /// Otherwise, the pending and current regions are never changed.
762    ///
763    /// The initial value for an opaque region is empty. Setting the pending
764    /// opaque region has copy semantics, and the wl_region object can be
765    /// destroyed immediately. A NULL wl_region causes the pending opaque
766    /// region to be set to empty.
767    ///
768    /// # Arguments
769    ///
770    /// - `region`: opaque region of the surface
771    #[inline]
772    pub fn try_send_set_opaque_region(
773        &self,
774        region: Option<&Rc<WlRegion>>,
775    ) -> Result<(), ObjectError> {
776        let (
777            arg0,
778        ) = (
779            region,
780        );
781        let arg0 = arg0.map(|a| a.core());
782        let core = self.core();
783        let Some(id) = core.server_obj_id.get() else {
784            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
785        };
786        let arg0_id = match arg0 {
787            None => 0,
788            Some(arg0) => match arg0.server_obj_id.get() {
789                None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("region"))),
790                Some(id) => id,
791            },
792        };
793        #[cfg(feature = "logging")]
794        if self.core.state.log {
795            #[cold]
796            fn log(state: &State, id: u32, arg0: u32) {
797                let (millis, micros) = time_since_epoch();
798                let prefix = &state.log_prefix;
799                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.set_opaque_region(region: wl_region#{})\n", id, arg0);
800                state.log(args);
801            }
802            log(&self.core.state, id, arg0_id);
803        }
804        let Some(endpoint) = &self.core.state.server else {
805            return Ok(());
806        };
807        if !endpoint.flush_queued.replace(true) {
808            self.core.state.add_flushable_endpoint(endpoint, None);
809        }
810        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
811        let outgoing = &mut *outgoing_ref;
812        let mut fmt = outgoing.formatter();
813        fmt.words([
814            id,
815            4,
816            arg0_id,
817        ]);
818        Ok(())
819    }
820
821    /// set opaque region
822    ///
823    /// This request sets the region of the surface that contains
824    /// opaque content.
825    ///
826    /// The opaque region is an optimization hint for the compositor
827    /// that lets it optimize the redrawing of content behind opaque
828    /// regions.  Setting an opaque region is not required for correct
829    /// behaviour, but marking transparent content as opaque will result
830    /// in repaint artifacts.
831    ///
832    /// The opaque region is specified in surface-local coordinates.
833    ///
834    /// The compositor ignores the parts of the opaque region that fall
835    /// outside of the surface.
836    ///
837    /// Opaque region is double-buffered state, see wl_surface.commit.
838    ///
839    /// wl_surface.set_opaque_region changes the pending opaque region.
840    /// wl_surface.commit copies the pending region to the current region.
841    /// Otherwise, the pending and current regions are never changed.
842    ///
843    /// The initial value for an opaque region is empty. Setting the pending
844    /// opaque region has copy semantics, and the wl_region object can be
845    /// destroyed immediately. A NULL wl_region causes the pending opaque
846    /// region to be set to empty.
847    ///
848    /// # Arguments
849    ///
850    /// - `region`: opaque region of the surface
851    #[inline]
852    pub fn send_set_opaque_region(
853        &self,
854        region: Option<&Rc<WlRegion>>,
855    ) {
856        let res = self.try_send_set_opaque_region(
857            region,
858        );
859        if let Err(e) = res {
860            log_send("wl_surface.set_opaque_region", &e);
861        }
862    }
863
864    /// Since when the set_input_region message is available.
865    pub const MSG__SET_INPUT_REGION__SINCE: u32 = 1;
866
867    /// set input region
868    ///
869    /// This request sets the region of the surface that can receive
870    /// pointer and touch events.
871    ///
872    /// Input events happening outside of this region will try the next
873    /// surface in the server surface stack. The compositor ignores the
874    /// parts of the input region that fall outside of the surface.
875    ///
876    /// The input region is specified in surface-local coordinates.
877    ///
878    /// Input region is double-buffered state, see wl_surface.commit.
879    ///
880    /// wl_surface.set_input_region changes the pending input region.
881    /// wl_surface.commit copies the pending region to the current region.
882    /// Otherwise the pending and current regions are never changed,
883    /// except cursor and icon surfaces are special cases, see
884    /// wl_pointer.set_cursor and wl_data_device.start_drag.
885    ///
886    /// The initial value for an input region is infinite. That means the
887    /// whole surface will accept input. Setting the pending input region
888    /// has copy semantics, and the wl_region object can be destroyed
889    /// immediately. A NULL wl_region causes the input region to be set
890    /// to infinite.
891    ///
892    /// # Arguments
893    ///
894    /// - `region`: input region of the surface
895    #[inline]
896    pub fn try_send_set_input_region(
897        &self,
898        region: Option<&Rc<WlRegion>>,
899    ) -> Result<(), ObjectError> {
900        let (
901            arg0,
902        ) = (
903            region,
904        );
905        let arg0 = arg0.map(|a| a.core());
906        let core = self.core();
907        let Some(id) = core.server_obj_id.get() else {
908            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
909        };
910        let arg0_id = match arg0 {
911            None => 0,
912            Some(arg0) => match arg0.server_obj_id.get() {
913                None => return Err(ObjectError(ObjectErrorKind::ArgNoServerId("region"))),
914                Some(id) => id,
915            },
916        };
917        #[cfg(feature = "logging")]
918        if self.core.state.log {
919            #[cold]
920            fn log(state: &State, id: u32, arg0: u32) {
921                let (millis, micros) = time_since_epoch();
922                let prefix = &state.log_prefix;
923                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.set_input_region(region: wl_region#{})\n", id, arg0);
924                state.log(args);
925            }
926            log(&self.core.state, id, arg0_id);
927        }
928        let Some(endpoint) = &self.core.state.server else {
929            return Ok(());
930        };
931        if !endpoint.flush_queued.replace(true) {
932            self.core.state.add_flushable_endpoint(endpoint, None);
933        }
934        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
935        let outgoing = &mut *outgoing_ref;
936        let mut fmt = outgoing.formatter();
937        fmt.words([
938            id,
939            5,
940            arg0_id,
941        ]);
942        Ok(())
943    }
944
945    /// set input region
946    ///
947    /// This request sets the region of the surface that can receive
948    /// pointer and touch events.
949    ///
950    /// Input events happening outside of this region will try the next
951    /// surface in the server surface stack. The compositor ignores the
952    /// parts of the input region that fall outside of the surface.
953    ///
954    /// The input region is specified in surface-local coordinates.
955    ///
956    /// Input region is double-buffered state, see wl_surface.commit.
957    ///
958    /// wl_surface.set_input_region changes the pending input region.
959    /// wl_surface.commit copies the pending region to the current region.
960    /// Otherwise the pending and current regions are never changed,
961    /// except cursor and icon surfaces are special cases, see
962    /// wl_pointer.set_cursor and wl_data_device.start_drag.
963    ///
964    /// The initial value for an input region is infinite. That means the
965    /// whole surface will accept input. Setting the pending input region
966    /// has copy semantics, and the wl_region object can be destroyed
967    /// immediately. A NULL wl_region causes the input region to be set
968    /// to infinite.
969    ///
970    /// # Arguments
971    ///
972    /// - `region`: input region of the surface
973    #[inline]
974    pub fn send_set_input_region(
975        &self,
976        region: Option<&Rc<WlRegion>>,
977    ) {
978        let res = self.try_send_set_input_region(
979            region,
980        );
981        if let Err(e) = res {
982            log_send("wl_surface.set_input_region", &e);
983        }
984    }
985
986    /// Since when the commit message is available.
987    pub const MSG__COMMIT__SINCE: u32 = 1;
988
989    /// commit pending surface state
990    ///
991    /// Surface state (input, opaque, and damage regions, attached buffers,
992    /// etc.) is double-buffered. Protocol requests modify the pending state,
993    /// as opposed to the active state in use by the compositor.
994    ///
995    /// A commit request atomically creates a content update from the pending
996    /// state, even if the pending state has not been touched. The content
997    /// update is placed in a queue until it becomes active. After commit, the
998    /// new pending state is as documented for each related request.
999    ///
1000    /// When the content update is applied, the wl_buffer is applied before all
1001    /// other state. This means that all coordinates in double-buffered state
1002    /// are relative to the newly attached wl_buffers, except for
1003    /// wl_surface.attach itself. If there is no newly attached wl_buffer, the
1004    /// coordinates are relative to the previous content update.
1005    ///
1006    /// All requests that need a commit to become effective are documented
1007    /// to affect double-buffered state.
1008    ///
1009    /// Other interfaces may add further double-buffered surface state.
1010    #[inline]
1011    pub fn try_send_commit(
1012        &self,
1013    ) -> Result<(), ObjectError> {
1014        let core = self.core();
1015        let Some(id) = core.server_obj_id.get() else {
1016            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
1017        };
1018        #[cfg(feature = "logging")]
1019        if self.core.state.log {
1020            #[cold]
1021            fn log(state: &State, id: u32) {
1022                let (millis, micros) = time_since_epoch();
1023                let prefix = &state.log_prefix;
1024                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.commit()\n", id);
1025                state.log(args);
1026            }
1027            log(&self.core.state, id);
1028        }
1029        let Some(endpoint) = &self.core.state.server else {
1030            return Ok(());
1031        };
1032        if !endpoint.flush_queued.replace(true) {
1033            self.core.state.add_flushable_endpoint(endpoint, None);
1034        }
1035        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1036        let outgoing = &mut *outgoing_ref;
1037        let mut fmt = outgoing.formatter();
1038        fmt.words([
1039            id,
1040            6,
1041        ]);
1042        Ok(())
1043    }
1044
1045    /// commit pending surface state
1046    ///
1047    /// Surface state (input, opaque, and damage regions, attached buffers,
1048    /// etc.) is double-buffered. Protocol requests modify the pending state,
1049    /// as opposed to the active state in use by the compositor.
1050    ///
1051    /// A commit request atomically creates a content update from the pending
1052    /// state, even if the pending state has not been touched. The content
1053    /// update is placed in a queue until it becomes active. After commit, the
1054    /// new pending state is as documented for each related request.
1055    ///
1056    /// When the content update is applied, the wl_buffer is applied before all
1057    /// other state. This means that all coordinates in double-buffered state
1058    /// are relative to the newly attached wl_buffers, except for
1059    /// wl_surface.attach itself. If there is no newly attached wl_buffer, the
1060    /// coordinates are relative to the previous content update.
1061    ///
1062    /// All requests that need a commit to become effective are documented
1063    /// to affect double-buffered state.
1064    ///
1065    /// Other interfaces may add further double-buffered surface state.
1066    #[inline]
1067    pub fn send_commit(
1068        &self,
1069    ) {
1070        let res = self.try_send_commit(
1071        );
1072        if let Err(e) = res {
1073            log_send("wl_surface.commit", &e);
1074        }
1075    }
1076
1077    /// Since when the enter message is available.
1078    pub const MSG__ENTER__SINCE: u32 = 1;
1079
1080    /// surface enters an output
1081    ///
1082    /// This is emitted whenever a surface's creation, movement, or resizing
1083    /// results in some part of it being within the scanout region of an
1084    /// output.
1085    ///
1086    /// Note that a surface may be overlapping with zero or more outputs.
1087    ///
1088    /// # Arguments
1089    ///
1090    /// - `output`: output entered by the surface
1091    #[inline]
1092    pub fn try_send_enter(
1093        &self,
1094        output: &Rc<WlOutput>,
1095    ) -> Result<(), ObjectError> {
1096        let (
1097            arg0,
1098        ) = (
1099            output,
1100        );
1101        let arg0 = arg0.core();
1102        let core = self.core();
1103        let client_ref = core.client.borrow();
1104        let Some(client) = &*client_ref else {
1105            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1106        };
1107        let id = core.client_obj_id.get().unwrap_or(0);
1108        if arg0.client_id.get() != Some(client.endpoint.id) {
1109            return Err(ObjectError(ObjectErrorKind::ArgNoClientId("output", client.endpoint.id)));
1110        }
1111        let arg0_id = arg0.client_obj_id.get().unwrap_or(0);
1112        #[cfg(feature = "logging")]
1113        if self.core.state.log {
1114            #[cold]
1115            fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
1116                let (millis, micros) = time_since_epoch();
1117                let prefix = &state.log_prefix;
1118                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_surface#{}.enter(output: wl_output#{})\n", client_id, id, arg0);
1119                state.log(args);
1120            }
1121            log(&self.core.state, client.endpoint.id, id, arg0_id);
1122        }
1123        let endpoint = &client.endpoint;
1124        if !endpoint.flush_queued.replace(true) {
1125            self.core.state.add_flushable_endpoint(endpoint, Some(client));
1126        }
1127        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1128        let outgoing = &mut *outgoing_ref;
1129        let mut fmt = outgoing.formatter();
1130        fmt.words([
1131            id,
1132            0,
1133            arg0_id,
1134        ]);
1135        Ok(())
1136    }
1137
1138    /// surface enters an output
1139    ///
1140    /// This is emitted whenever a surface's creation, movement, or resizing
1141    /// results in some part of it being within the scanout region of an
1142    /// output.
1143    ///
1144    /// Note that a surface may be overlapping with zero or more outputs.
1145    ///
1146    /// # Arguments
1147    ///
1148    /// - `output`: output entered by the surface
1149    #[inline]
1150    pub fn send_enter(
1151        &self,
1152        output: &Rc<WlOutput>,
1153    ) {
1154        let res = self.try_send_enter(
1155            output,
1156        );
1157        if let Err(e) = res {
1158            log_send("wl_surface.enter", &e);
1159        }
1160    }
1161
1162    /// Since when the leave message is available.
1163    pub const MSG__LEAVE__SINCE: u32 = 1;
1164
1165    /// surface leaves an output
1166    ///
1167    /// This is emitted whenever a surface's creation, movement, or resizing
1168    /// results in it no longer having any part of it within the scanout region
1169    /// of an output.
1170    ///
1171    /// Clients should not use the number of outputs the surface is on for frame
1172    /// throttling purposes. The surface might be hidden even if no leave event
1173    /// has been sent, and the compositor might expect new surface content
1174    /// updates even if no enter event has been sent. The frame event should be
1175    /// used instead.
1176    ///
1177    /// # Arguments
1178    ///
1179    /// - `output`: output left by the surface
1180    #[inline]
1181    pub fn try_send_leave(
1182        &self,
1183        output: &Rc<WlOutput>,
1184    ) -> Result<(), ObjectError> {
1185        let (
1186            arg0,
1187        ) = (
1188            output,
1189        );
1190        let arg0 = arg0.core();
1191        let core = self.core();
1192        let client_ref = core.client.borrow();
1193        let Some(client) = &*client_ref else {
1194            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1195        };
1196        let id = core.client_obj_id.get().unwrap_or(0);
1197        if arg0.client_id.get() != Some(client.endpoint.id) {
1198            return Err(ObjectError(ObjectErrorKind::ArgNoClientId("output", client.endpoint.id)));
1199        }
1200        let arg0_id = arg0.client_obj_id.get().unwrap_or(0);
1201        #[cfg(feature = "logging")]
1202        if self.core.state.log {
1203            #[cold]
1204            fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
1205                let (millis, micros) = time_since_epoch();
1206                let prefix = &state.log_prefix;
1207                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_surface#{}.leave(output: wl_output#{})\n", client_id, id, arg0);
1208                state.log(args);
1209            }
1210            log(&self.core.state, client.endpoint.id, id, arg0_id);
1211        }
1212        let endpoint = &client.endpoint;
1213        if !endpoint.flush_queued.replace(true) {
1214            self.core.state.add_flushable_endpoint(endpoint, Some(client));
1215        }
1216        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1217        let outgoing = &mut *outgoing_ref;
1218        let mut fmt = outgoing.formatter();
1219        fmt.words([
1220            id,
1221            1,
1222            arg0_id,
1223        ]);
1224        Ok(())
1225    }
1226
1227    /// surface leaves an output
1228    ///
1229    /// This is emitted whenever a surface's creation, movement, or resizing
1230    /// results in it no longer having any part of it within the scanout region
1231    /// of an output.
1232    ///
1233    /// Clients should not use the number of outputs the surface is on for frame
1234    /// throttling purposes. The surface might be hidden even if no leave event
1235    /// has been sent, and the compositor might expect new surface content
1236    /// updates even if no enter event has been sent. The frame event should be
1237    /// used instead.
1238    ///
1239    /// # Arguments
1240    ///
1241    /// - `output`: output left by the surface
1242    #[inline]
1243    pub fn send_leave(
1244        &self,
1245        output: &Rc<WlOutput>,
1246    ) {
1247        let res = self.try_send_leave(
1248            output,
1249        );
1250        if let Err(e) = res {
1251            log_send("wl_surface.leave", &e);
1252        }
1253    }
1254
1255    /// Since when the set_buffer_transform message is available.
1256    pub const MSG__SET_BUFFER_TRANSFORM__SINCE: u32 = 2;
1257
1258    /// sets the buffer transformation
1259    ///
1260    /// This request sets the transformation that the client has already applied
1261    /// to the content of the buffer. The accepted values for the transform
1262    /// parameter are the values for wl_output.transform.
1263    ///
1264    /// The compositor applies the inverse of this transformation whenever it
1265    /// uses the buffer contents.
1266    ///
1267    /// Buffer transform is double-buffered state, see wl_surface.commit.
1268    ///
1269    /// A newly created surface has its buffer transformation set to normal.
1270    ///
1271    /// wl_surface.set_buffer_transform changes the pending buffer
1272    /// transformation. wl_surface.commit copies the pending buffer
1273    /// transformation to the current one. Otherwise, the pending and current
1274    /// values are never changed.
1275    ///
1276    /// The purpose of this request is to allow clients to render content
1277    /// according to the output transform, thus permitting the compositor to
1278    /// use certain optimizations even if the display is rotated. Using
1279    /// hardware overlays and scanning out a client buffer for fullscreen
1280    /// surfaces are examples of such optimizations. Those optimizations are
1281    /// highly dependent on the compositor implementation, so the use of this
1282    /// request should be considered on a case-by-case basis.
1283    ///
1284    /// Note that if the transform value includes 90 or 270 degree rotation,
1285    /// the width of the buffer will become the surface height and the height
1286    /// of the buffer will become the surface width.
1287    ///
1288    /// If transform is not one of the values from the
1289    /// wl_output.transform enum the invalid_transform protocol error
1290    /// is raised.
1291    ///
1292    /// # Arguments
1293    ///
1294    /// - `transform`: transform for interpreting buffer contents
1295    #[inline]
1296    pub fn try_send_set_buffer_transform(
1297        &self,
1298        transform: WlOutputTransform,
1299    ) -> Result<(), ObjectError> {
1300        let (
1301            arg0,
1302        ) = (
1303            transform,
1304        );
1305        let core = self.core();
1306        let Some(id) = core.server_obj_id.get() else {
1307            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
1308        };
1309        #[cfg(feature = "logging")]
1310        if self.core.state.log {
1311            #[cold]
1312            fn log(state: &State, id: u32, arg0: WlOutputTransform) {
1313                let (millis, micros) = time_since_epoch();
1314                let prefix = &state.log_prefix;
1315                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.set_buffer_transform(transform: {:?})\n", id, arg0);
1316                state.log(args);
1317            }
1318            log(&self.core.state, id, arg0);
1319        }
1320        let Some(endpoint) = &self.core.state.server else {
1321            return Ok(());
1322        };
1323        if !endpoint.flush_queued.replace(true) {
1324            self.core.state.add_flushable_endpoint(endpoint, None);
1325        }
1326        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1327        let outgoing = &mut *outgoing_ref;
1328        let mut fmt = outgoing.formatter();
1329        fmt.words([
1330            id,
1331            7,
1332            arg0.0,
1333        ]);
1334        Ok(())
1335    }
1336
1337    /// sets the buffer transformation
1338    ///
1339    /// This request sets the transformation that the client has already applied
1340    /// to the content of the buffer. The accepted values for the transform
1341    /// parameter are the values for wl_output.transform.
1342    ///
1343    /// The compositor applies the inverse of this transformation whenever it
1344    /// uses the buffer contents.
1345    ///
1346    /// Buffer transform is double-buffered state, see wl_surface.commit.
1347    ///
1348    /// A newly created surface has its buffer transformation set to normal.
1349    ///
1350    /// wl_surface.set_buffer_transform changes the pending buffer
1351    /// transformation. wl_surface.commit copies the pending buffer
1352    /// transformation to the current one. Otherwise, the pending and current
1353    /// values are never changed.
1354    ///
1355    /// The purpose of this request is to allow clients to render content
1356    /// according to the output transform, thus permitting the compositor to
1357    /// use certain optimizations even if the display is rotated. Using
1358    /// hardware overlays and scanning out a client buffer for fullscreen
1359    /// surfaces are examples of such optimizations. Those optimizations are
1360    /// highly dependent on the compositor implementation, so the use of this
1361    /// request should be considered on a case-by-case basis.
1362    ///
1363    /// Note that if the transform value includes 90 or 270 degree rotation,
1364    /// the width of the buffer will become the surface height and the height
1365    /// of the buffer will become the surface width.
1366    ///
1367    /// If transform is not one of the values from the
1368    /// wl_output.transform enum the invalid_transform protocol error
1369    /// is raised.
1370    ///
1371    /// # Arguments
1372    ///
1373    /// - `transform`: transform for interpreting buffer contents
1374    #[inline]
1375    pub fn send_set_buffer_transform(
1376        &self,
1377        transform: WlOutputTransform,
1378    ) {
1379        let res = self.try_send_set_buffer_transform(
1380            transform,
1381        );
1382        if let Err(e) = res {
1383            log_send("wl_surface.set_buffer_transform", &e);
1384        }
1385    }
1386
1387    /// Since when the set_buffer_scale message is available.
1388    pub const MSG__SET_BUFFER_SCALE__SINCE: u32 = 3;
1389
1390    /// sets the buffer scaling factor
1391    ///
1392    /// This request sets an optional scaling factor on how the compositor
1393    /// interprets the contents of the buffer attached to the window.
1394    ///
1395    /// Buffer scale is double-buffered state, see wl_surface.commit.
1396    ///
1397    /// A newly created surface has its buffer scale set to 1.
1398    ///
1399    /// wl_surface.set_buffer_scale changes the pending buffer scale.
1400    /// wl_surface.commit copies the pending buffer scale to the current one.
1401    /// Otherwise, the pending and current values are never changed.
1402    ///
1403    /// The purpose of this request is to allow clients to supply higher
1404    /// resolution buffer data for use on high resolution outputs. It is
1405    /// intended that you pick the same buffer scale as the scale of the
1406    /// output that the surface is displayed on. This means the compositor
1407    /// can avoid scaling when rendering the surface on that output.
1408    ///
1409    /// Note that if the scale is larger than 1, then you have to attach
1410    /// a buffer that is larger (by a factor of scale in each dimension)
1411    /// than the desired surface size.
1412    ///
1413    /// If scale is not greater than 0 the invalid_scale protocol error is
1414    /// raised.
1415    ///
1416    /// # Arguments
1417    ///
1418    /// - `scale`: scale for interpreting buffer contents
1419    #[inline]
1420    pub fn try_send_set_buffer_scale(
1421        &self,
1422        scale: i32,
1423    ) -> Result<(), ObjectError> {
1424        let (
1425            arg0,
1426        ) = (
1427            scale,
1428        );
1429        let core = self.core();
1430        let Some(id) = core.server_obj_id.get() else {
1431            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
1432        };
1433        #[cfg(feature = "logging")]
1434        if self.core.state.log {
1435            #[cold]
1436            fn log(state: &State, id: u32, arg0: i32) {
1437                let (millis, micros) = time_since_epoch();
1438                let prefix = &state.log_prefix;
1439                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.set_buffer_scale(scale: {})\n", id, arg0);
1440                state.log(args);
1441            }
1442            log(&self.core.state, id, arg0);
1443        }
1444        let Some(endpoint) = &self.core.state.server else {
1445            return Ok(());
1446        };
1447        if !endpoint.flush_queued.replace(true) {
1448            self.core.state.add_flushable_endpoint(endpoint, None);
1449        }
1450        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1451        let outgoing = &mut *outgoing_ref;
1452        let mut fmt = outgoing.formatter();
1453        fmt.words([
1454            id,
1455            8,
1456            arg0 as u32,
1457        ]);
1458        Ok(())
1459    }
1460
1461    /// sets the buffer scaling factor
1462    ///
1463    /// This request sets an optional scaling factor on how the compositor
1464    /// interprets the contents of the buffer attached to the window.
1465    ///
1466    /// Buffer scale is double-buffered state, see wl_surface.commit.
1467    ///
1468    /// A newly created surface has its buffer scale set to 1.
1469    ///
1470    /// wl_surface.set_buffer_scale changes the pending buffer scale.
1471    /// wl_surface.commit copies the pending buffer scale to the current one.
1472    /// Otherwise, the pending and current values are never changed.
1473    ///
1474    /// The purpose of this request is to allow clients to supply higher
1475    /// resolution buffer data for use on high resolution outputs. It is
1476    /// intended that you pick the same buffer scale as the scale of the
1477    /// output that the surface is displayed on. This means the compositor
1478    /// can avoid scaling when rendering the surface on that output.
1479    ///
1480    /// Note that if the scale is larger than 1, then you have to attach
1481    /// a buffer that is larger (by a factor of scale in each dimension)
1482    /// than the desired surface size.
1483    ///
1484    /// If scale is not greater than 0 the invalid_scale protocol error is
1485    /// raised.
1486    ///
1487    /// # Arguments
1488    ///
1489    /// - `scale`: scale for interpreting buffer contents
1490    #[inline]
1491    pub fn send_set_buffer_scale(
1492        &self,
1493        scale: i32,
1494    ) {
1495        let res = self.try_send_set_buffer_scale(
1496            scale,
1497        );
1498        if let Err(e) = res {
1499            log_send("wl_surface.set_buffer_scale", &e);
1500        }
1501    }
1502
1503    /// Since when the damage_buffer message is available.
1504    pub const MSG__DAMAGE_BUFFER__SINCE: u32 = 4;
1505
1506    /// mark part of the surface damaged using buffer coordinates
1507    ///
1508    /// This request is used to describe the regions where the pending
1509    /// buffer is different from the current surface contents, and where
1510    /// the surface therefore needs to be repainted. The compositor
1511    /// ignores the parts of the damage that fall outside of the surface.
1512    ///
1513    /// Damage is double-buffered state, see wl_surface.commit.
1514    ///
1515    /// The damage rectangle is specified in buffer coordinates,
1516    /// where x and y specify the upper left corner of the damage rectangle.
1517    ///
1518    /// The initial value for pending damage is empty: no damage.
1519    /// wl_surface.damage_buffer adds pending damage: the new pending
1520    /// damage is the union of old pending damage and the given rectangle.
1521    ///
1522    /// wl_surface.commit assigns pending damage as the current damage,
1523    /// and clears pending damage. The server will clear the current
1524    /// damage as it repaints the surface.
1525    ///
1526    /// This request differs from wl_surface.damage in only one way - it
1527    /// takes damage in buffer coordinates instead of surface-local
1528    /// coordinates. While this generally is more intuitive than surface
1529    /// coordinates, it is especially desirable when using wp_viewport
1530    /// or when a drawing library (like EGL) is unaware of buffer scale
1531    /// and buffer transform.
1532    ///
1533    /// Note: Because buffer transformation changes and damage requests may
1534    /// be interleaved in the protocol stream, it is impossible to determine
1535    /// the actual mapping between surface and buffer damage until
1536    /// wl_surface.commit time. Therefore, compositors wishing to take both
1537    /// kinds of damage into account will have to accumulate damage from the
1538    /// two requests separately and only transform from one to the other
1539    /// after receiving the wl_surface.commit.
1540    ///
1541    /// # Arguments
1542    ///
1543    /// - `x`: buffer-local x coordinate
1544    /// - `y`: buffer-local y coordinate
1545    /// - `width`: width of damage rectangle
1546    /// - `height`: height of damage rectangle
1547    #[inline]
1548    pub fn try_send_damage_buffer(
1549        &self,
1550        x: i32,
1551        y: i32,
1552        width: i32,
1553        height: i32,
1554    ) -> Result<(), ObjectError> {
1555        let (
1556            arg0,
1557            arg1,
1558            arg2,
1559            arg3,
1560        ) = (
1561            x,
1562            y,
1563            width,
1564            height,
1565        );
1566        let core = self.core();
1567        let Some(id) = core.server_obj_id.get() else {
1568            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
1569        };
1570        #[cfg(feature = "logging")]
1571        if self.core.state.log {
1572            #[cold]
1573            fn log(state: &State, id: u32, arg0: i32, arg1: i32, arg2: i32, arg3: i32) {
1574                let (millis, micros) = time_since_epoch();
1575                let prefix = &state.log_prefix;
1576                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.damage_buffer(x: {}, y: {}, width: {}, height: {})\n", id, arg0, arg1, arg2, arg3);
1577                state.log(args);
1578            }
1579            log(&self.core.state, id, arg0, arg1, arg2, arg3);
1580        }
1581        let Some(endpoint) = &self.core.state.server else {
1582            return Ok(());
1583        };
1584        if !endpoint.flush_queued.replace(true) {
1585            self.core.state.add_flushable_endpoint(endpoint, None);
1586        }
1587        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1588        let outgoing = &mut *outgoing_ref;
1589        let mut fmt = outgoing.formatter();
1590        fmt.words([
1591            id,
1592            9,
1593            arg0 as u32,
1594            arg1 as u32,
1595            arg2 as u32,
1596            arg3 as u32,
1597        ]);
1598        Ok(())
1599    }
1600
1601    /// mark part of the surface damaged using buffer coordinates
1602    ///
1603    /// This request is used to describe the regions where the pending
1604    /// buffer is different from the current surface contents, and where
1605    /// the surface therefore needs to be repainted. The compositor
1606    /// ignores the parts of the damage that fall outside of the surface.
1607    ///
1608    /// Damage is double-buffered state, see wl_surface.commit.
1609    ///
1610    /// The damage rectangle is specified in buffer coordinates,
1611    /// where x and y specify the upper left corner of the damage rectangle.
1612    ///
1613    /// The initial value for pending damage is empty: no damage.
1614    /// wl_surface.damage_buffer adds pending damage: the new pending
1615    /// damage is the union of old pending damage and the given rectangle.
1616    ///
1617    /// wl_surface.commit assigns pending damage as the current damage,
1618    /// and clears pending damage. The server will clear the current
1619    /// damage as it repaints the surface.
1620    ///
1621    /// This request differs from wl_surface.damage in only one way - it
1622    /// takes damage in buffer coordinates instead of surface-local
1623    /// coordinates. While this generally is more intuitive than surface
1624    /// coordinates, it is especially desirable when using wp_viewport
1625    /// or when a drawing library (like EGL) is unaware of buffer scale
1626    /// and buffer transform.
1627    ///
1628    /// Note: Because buffer transformation changes and damage requests may
1629    /// be interleaved in the protocol stream, it is impossible to determine
1630    /// the actual mapping between surface and buffer damage until
1631    /// wl_surface.commit time. Therefore, compositors wishing to take both
1632    /// kinds of damage into account will have to accumulate damage from the
1633    /// two requests separately and only transform from one to the other
1634    /// after receiving the wl_surface.commit.
1635    ///
1636    /// # Arguments
1637    ///
1638    /// - `x`: buffer-local x coordinate
1639    /// - `y`: buffer-local y coordinate
1640    /// - `width`: width of damage rectangle
1641    /// - `height`: height of damage rectangle
1642    #[inline]
1643    pub fn send_damage_buffer(
1644        &self,
1645        x: i32,
1646        y: i32,
1647        width: i32,
1648        height: i32,
1649    ) {
1650        let res = self.try_send_damage_buffer(
1651            x,
1652            y,
1653            width,
1654            height,
1655        );
1656        if let Err(e) = res {
1657            log_send("wl_surface.damage_buffer", &e);
1658        }
1659    }
1660
1661    /// Since when the offset message is available.
1662    pub const MSG__OFFSET__SINCE: u32 = 5;
1663
1664    /// set the surface contents offset
1665    ///
1666    /// The x and y arguments specify the location of the new pending
1667    /// buffer's upper left corner, relative to the current buffer's upper
1668    /// left corner, in surface-local coordinates. In other words, the
1669    /// x and y, combined with the new surface size define in which
1670    /// directions the surface's size changes.
1671    ///
1672    /// The exact semantics of wl_surface.offset are role-specific. Refer to
1673    /// the documentation of specific roles for more information.
1674    ///
1675    /// Surface location offset is double-buffered state, see
1676    /// wl_surface.commit.
1677    ///
1678    /// This request is semantically equivalent to and the replaces the x and y
1679    /// arguments in the wl_surface.attach request in wl_surface versions prior
1680    /// to 5. See wl_surface.attach for details.
1681    ///
1682    /// # Arguments
1683    ///
1684    /// - `x`: surface-local x coordinate
1685    /// - `y`: surface-local y coordinate
1686    #[inline]
1687    pub fn try_send_offset(
1688        &self,
1689        x: i32,
1690        y: i32,
1691    ) -> Result<(), ObjectError> {
1692        let (
1693            arg0,
1694            arg1,
1695        ) = (
1696            x,
1697            y,
1698        );
1699        let core = self.core();
1700        let Some(id) = core.server_obj_id.get() else {
1701            return Err(ObjectError(ObjectErrorKind::ReceiverNoServerId));
1702        };
1703        #[cfg(feature = "logging")]
1704        if self.core.state.log {
1705            #[cold]
1706            fn log(state: &State, id: u32, arg0: i32, arg1: i32) {
1707                let (millis, micros) = time_since_epoch();
1708                let prefix = &state.log_prefix;
1709                let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      <= wl_surface#{}.offset(x: {}, y: {})\n", id, arg0, arg1);
1710                state.log(args);
1711            }
1712            log(&self.core.state, id, arg0, arg1);
1713        }
1714        let Some(endpoint) = &self.core.state.server else {
1715            return Ok(());
1716        };
1717        if !endpoint.flush_queued.replace(true) {
1718            self.core.state.add_flushable_endpoint(endpoint, None);
1719        }
1720        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1721        let outgoing = &mut *outgoing_ref;
1722        let mut fmt = outgoing.formatter();
1723        fmt.words([
1724            id,
1725            10,
1726            arg0 as u32,
1727            arg1 as u32,
1728        ]);
1729        Ok(())
1730    }
1731
1732    /// set the surface contents offset
1733    ///
1734    /// The x and y arguments specify the location of the new pending
1735    /// buffer's upper left corner, relative to the current buffer's upper
1736    /// left corner, in surface-local coordinates. In other words, the
1737    /// x and y, combined with the new surface size define in which
1738    /// directions the surface's size changes.
1739    ///
1740    /// The exact semantics of wl_surface.offset are role-specific. Refer to
1741    /// the documentation of specific roles for more information.
1742    ///
1743    /// Surface location offset is double-buffered state, see
1744    /// wl_surface.commit.
1745    ///
1746    /// This request is semantically equivalent to and the replaces the x and y
1747    /// arguments in the wl_surface.attach request in wl_surface versions prior
1748    /// to 5. See wl_surface.attach for details.
1749    ///
1750    /// # Arguments
1751    ///
1752    /// - `x`: surface-local x coordinate
1753    /// - `y`: surface-local y coordinate
1754    #[inline]
1755    pub fn send_offset(
1756        &self,
1757        x: i32,
1758        y: i32,
1759    ) {
1760        let res = self.try_send_offset(
1761            x,
1762            y,
1763        );
1764        if let Err(e) = res {
1765            log_send("wl_surface.offset", &e);
1766        }
1767    }
1768
1769    /// Since when the preferred_buffer_scale message is available.
1770    pub const MSG__PREFERRED_BUFFER_SCALE__SINCE: u32 = 6;
1771
1772    /// preferred buffer scale for the surface
1773    ///
1774    /// This event indicates the preferred buffer scale for this surface. It is
1775    /// sent whenever the compositor's preference changes.
1776    ///
1777    /// Before receiving this event the preferred buffer scale for this surface
1778    /// is 1.
1779    ///
1780    /// It is intended that scaling aware clients use this event to scale their
1781    /// content and use wl_surface.set_buffer_scale to indicate the scale they
1782    /// have rendered with. This allows clients to supply a higher detail
1783    /// buffer.
1784    ///
1785    /// The compositor shall emit a scale value greater than 0.
1786    ///
1787    /// # Arguments
1788    ///
1789    /// - `factor`: preferred scaling factor
1790    #[inline]
1791    pub fn try_send_preferred_buffer_scale(
1792        &self,
1793        factor: i32,
1794    ) -> Result<(), ObjectError> {
1795        let (
1796            arg0,
1797        ) = (
1798            factor,
1799        );
1800        let core = self.core();
1801        let client_ref = core.client.borrow();
1802        let Some(client) = &*client_ref else {
1803            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1804        };
1805        let id = core.client_obj_id.get().unwrap_or(0);
1806        #[cfg(feature = "logging")]
1807        if self.core.state.log {
1808            #[cold]
1809            fn log(state: &State, client_id: u64, id: u32, arg0: i32) {
1810                let (millis, micros) = time_since_epoch();
1811                let prefix = &state.log_prefix;
1812                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_surface#{}.preferred_buffer_scale(factor: {})\n", client_id, id, arg0);
1813                state.log(args);
1814            }
1815            log(&self.core.state, client.endpoint.id, id, arg0);
1816        }
1817        let endpoint = &client.endpoint;
1818        if !endpoint.flush_queued.replace(true) {
1819            self.core.state.add_flushable_endpoint(endpoint, Some(client));
1820        }
1821        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1822        let outgoing = &mut *outgoing_ref;
1823        let mut fmt = outgoing.formatter();
1824        fmt.words([
1825            id,
1826            2,
1827            arg0 as u32,
1828        ]);
1829        Ok(())
1830    }
1831
1832    /// preferred buffer scale for the surface
1833    ///
1834    /// This event indicates the preferred buffer scale for this surface. It is
1835    /// sent whenever the compositor's preference changes.
1836    ///
1837    /// Before receiving this event the preferred buffer scale for this surface
1838    /// is 1.
1839    ///
1840    /// It is intended that scaling aware clients use this event to scale their
1841    /// content and use wl_surface.set_buffer_scale to indicate the scale they
1842    /// have rendered with. This allows clients to supply a higher detail
1843    /// buffer.
1844    ///
1845    /// The compositor shall emit a scale value greater than 0.
1846    ///
1847    /// # Arguments
1848    ///
1849    /// - `factor`: preferred scaling factor
1850    #[inline]
1851    pub fn send_preferred_buffer_scale(
1852        &self,
1853        factor: i32,
1854    ) {
1855        let res = self.try_send_preferred_buffer_scale(
1856            factor,
1857        );
1858        if let Err(e) = res {
1859            log_send("wl_surface.preferred_buffer_scale", &e);
1860        }
1861    }
1862
1863    /// Since when the preferred_buffer_transform message is available.
1864    pub const MSG__PREFERRED_BUFFER_TRANSFORM__SINCE: u32 = 6;
1865
1866    /// preferred buffer transform for the surface
1867    ///
1868    /// This event indicates the preferred buffer transform for this surface.
1869    /// It is sent whenever the compositor's preference changes.
1870    ///
1871    /// Before receiving this event the preferred buffer transform for this
1872    /// surface is normal.
1873    ///
1874    /// Applying this transformation to the surface buffer contents and using
1875    /// wl_surface.set_buffer_transform might allow the compositor to use the
1876    /// surface buffer more efficiently.
1877    ///
1878    /// # Arguments
1879    ///
1880    /// - `transform`: preferred transform
1881    #[inline]
1882    pub fn try_send_preferred_buffer_transform(
1883        &self,
1884        transform: WlOutputTransform,
1885    ) -> Result<(), ObjectError> {
1886        let (
1887            arg0,
1888        ) = (
1889            transform,
1890        );
1891        let core = self.core();
1892        let client_ref = core.client.borrow();
1893        let Some(client) = &*client_ref else {
1894            return Err(ObjectError(ObjectErrorKind::ReceiverNoClient));
1895        };
1896        let id = core.client_obj_id.get().unwrap_or(0);
1897        #[cfg(feature = "logging")]
1898        if self.core.state.log {
1899            #[cold]
1900            fn log(state: &State, client_id: u64, id: u32, arg0: WlOutputTransform) {
1901                let (millis, micros) = time_since_epoch();
1902                let prefix = &state.log_prefix;
1903                let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} <= wl_surface#{}.preferred_buffer_transform(transform: {:?})\n", client_id, id, arg0);
1904                state.log(args);
1905            }
1906            log(&self.core.state, client.endpoint.id, id, arg0);
1907        }
1908        let endpoint = &client.endpoint;
1909        if !endpoint.flush_queued.replace(true) {
1910            self.core.state.add_flushable_endpoint(endpoint, Some(client));
1911        }
1912        let mut outgoing_ref = endpoint.outgoing.borrow_mut();
1913        let outgoing = &mut *outgoing_ref;
1914        let mut fmt = outgoing.formatter();
1915        fmt.words([
1916            id,
1917            3,
1918            arg0.0,
1919        ]);
1920        Ok(())
1921    }
1922
1923    /// preferred buffer transform for the surface
1924    ///
1925    /// This event indicates the preferred buffer transform for this surface.
1926    /// It is sent whenever the compositor's preference changes.
1927    ///
1928    /// Before receiving this event the preferred buffer transform for this
1929    /// surface is normal.
1930    ///
1931    /// Applying this transformation to the surface buffer contents and using
1932    /// wl_surface.set_buffer_transform might allow the compositor to use the
1933    /// surface buffer more efficiently.
1934    ///
1935    /// # Arguments
1936    ///
1937    /// - `transform`: preferred transform
1938    #[inline]
1939    pub fn send_preferred_buffer_transform(
1940        &self,
1941        transform: WlOutputTransform,
1942    ) {
1943        let res = self.try_send_preferred_buffer_transform(
1944            transform,
1945        );
1946        if let Err(e) = res {
1947            log_send("wl_surface.preferred_buffer_transform", &e);
1948        }
1949    }
1950}
1951
1952/// A message handler for [`WlSurface`] proxies.
1953pub trait WlSurfaceHandler: Any {
1954    /// Event handler for wl_display.delete_id messages deleting the ID of this object.
1955    ///
1956    /// The default handler forwards the event to the client, if any.
1957    #[inline]
1958    fn delete_id(&mut self, slf: &Rc<WlSurface>) {
1959        slf.core.delete_id();
1960    }
1961
1962    /// delete surface
1963    ///
1964    /// Deletes the surface and invalidates its object ID.
1965    #[inline]
1966    fn handle_destroy(
1967        &mut self,
1968        slf: &Rc<WlSurface>,
1969    ) {
1970        if !slf.core.forward_to_server.get() {
1971            return;
1972        }
1973        let res = slf.try_send_destroy(
1974        );
1975        if let Err(e) = res {
1976            log_forward("wl_surface.destroy", &e);
1977        }
1978    }
1979
1980    /// set the surface contents
1981    ///
1982    /// Set a buffer as the content of this surface.
1983    ///
1984    /// The new size of the surface is calculated based on the buffer
1985    /// size transformed by the inverse buffer_transform and the
1986    /// inverse buffer_scale. This means that at commit time the supplied
1987    /// buffer size must be an integer multiple of the buffer_scale. If
1988    /// that's not the case, an invalid_size error is sent.
1989    ///
1990    /// The x and y arguments specify the location of the new pending
1991    /// buffer's upper left corner, relative to the current buffer's upper
1992    /// left corner, in surface-local coordinates. In other words, the
1993    /// x and y, combined with the new surface size define in which
1994    /// directions the surface's size changes. Setting anything other than 0
1995    /// as x and y arguments is discouraged, and should instead be replaced
1996    /// with using the separate wl_surface.offset request.
1997    ///
1998    /// When the bound wl_surface version is 5 or higher, passing any
1999    /// non-zero x or y is a protocol violation, and will result in an
2000    /// 'invalid_offset' error being raised. The x and y arguments are ignored
2001    /// and do not change the pending state. To achieve equivalent semantics,
2002    /// use wl_surface.offset.
2003    ///
2004    /// Surface contents are double-buffered state, see wl_surface.commit.
2005    ///
2006    /// The initial surface contents are void; there is no content.
2007    /// wl_surface.attach assigns the given wl_buffer as the pending
2008    /// wl_buffer. wl_surface.commit makes the pending wl_buffer the new
2009    /// surface contents, and the size of the surface becomes the size
2010    /// calculated from the wl_buffer, as described above. After commit,
2011    /// there is no pending buffer until the next attach.
2012    ///
2013    /// Committing a pending wl_buffer allows the compositor to read the
2014    /// pixels in the wl_buffer. The compositor may access the pixels at
2015    /// any time after the wl_surface.commit request. When the compositor
2016    /// will not access the pixels anymore, it will send the
2017    /// wl_buffer.release event. Only after receiving wl_buffer.release,
2018    /// the client may reuse the wl_buffer. A wl_buffer that has been
2019    /// attached and then replaced by another attach instead of committed
2020    /// will not receive a release event, and is not used by the
2021    /// compositor.
2022    ///
2023    /// If a pending wl_buffer has been committed to more than one wl_surface,
2024    /// the delivery of wl_buffer.release events becomes undefined. A well
2025    /// behaved client should not rely on wl_buffer.release events in this
2026    /// case. Alternatively, a client could create multiple wl_buffer objects
2027    /// from the same backing storage or use a protocol extension providing
2028    /// per-commit release notifications.
2029    ///
2030    /// Destroying the wl_buffer after wl_buffer.release does not change
2031    /// the surface contents. Destroying the wl_buffer before wl_buffer.release
2032    /// is allowed as long as the underlying buffer storage isn't re-used (this
2033    /// can happen e.g. on client process termination). However, if the client
2034    /// destroys the wl_buffer before receiving the wl_buffer.release event and
2035    /// mutates the underlying buffer storage, the surface contents become
2036    /// undefined immediately.
2037    ///
2038    /// If wl_surface.attach is sent with a NULL wl_buffer, the
2039    /// following wl_surface.commit will remove the surface content.
2040    ///
2041    /// If a pending wl_buffer has been destroyed, the result is not specified.
2042    /// Many compositors are known to remove the surface content on the following
2043    /// wl_surface.commit, but this behaviour is not universal. Clients seeking to
2044    /// maximise compatibility should not destroy pending buffers and should
2045    /// ensure that they explicitly remove content from surfaces, even after
2046    /// destroying buffers.
2047    ///
2048    /// # Arguments
2049    ///
2050    /// - `buffer`: buffer of surface contents
2051    /// - `x`: surface-local x coordinate
2052    /// - `y`: surface-local y coordinate
2053    ///
2054    /// All borrowed proxies passed to this function are guaranteed to be
2055    /// immutable and non-null.
2056    #[inline]
2057    fn handle_attach(
2058        &mut self,
2059        slf: &Rc<WlSurface>,
2060        buffer: Option<&Rc<WlBuffer>>,
2061        x: i32,
2062        y: i32,
2063    ) {
2064        if !slf.core.forward_to_server.get() {
2065            return;
2066        }
2067        let res = slf.try_send_attach(
2068            buffer,
2069            x,
2070            y,
2071        );
2072        if let Err(e) = res {
2073            log_forward("wl_surface.attach", &e);
2074        }
2075    }
2076
2077    /// mark part of the surface damaged
2078    ///
2079    /// This request is used to describe the regions where the pending
2080    /// buffer is different from the current surface contents, and where
2081    /// the surface therefore needs to be repainted. The compositor
2082    /// ignores the parts of the damage that fall outside of the surface.
2083    ///
2084    /// Damage is double-buffered state, see wl_surface.commit.
2085    ///
2086    /// The damage rectangle is specified in surface-local coordinates,
2087    /// where x and y specify the upper left corner of the damage rectangle.
2088    ///
2089    /// The initial value for pending damage is empty: no damage.
2090    /// wl_surface.damage adds pending damage: the new pending damage
2091    /// is the union of old pending damage and the given rectangle.
2092    ///
2093    /// wl_surface.commit assigns pending damage as the current damage,
2094    /// and clears pending damage. The server will clear the current
2095    /// damage as it repaints the surface.
2096    ///
2097    /// Note! New clients should not use this request. Instead damage can be
2098    /// posted with wl_surface.damage_buffer which uses buffer coordinates
2099    /// instead of surface coordinates.
2100    ///
2101    /// # Arguments
2102    ///
2103    /// - `x`: surface-local x coordinate
2104    /// - `y`: surface-local y coordinate
2105    /// - `width`: width of damage rectangle
2106    /// - `height`: height of damage rectangle
2107    #[inline]
2108    fn handle_damage(
2109        &mut self,
2110        slf: &Rc<WlSurface>,
2111        x: i32,
2112        y: i32,
2113        width: i32,
2114        height: i32,
2115    ) {
2116        if !slf.core.forward_to_server.get() {
2117            return;
2118        }
2119        let res = slf.try_send_damage(
2120            x,
2121            y,
2122            width,
2123            height,
2124        );
2125        if let Err(e) = res {
2126            log_forward("wl_surface.damage", &e);
2127        }
2128    }
2129
2130    /// request a frame throttling hint
2131    ///
2132    /// Request a notification when it is a good time to start drawing a new
2133    /// frame, by creating a frame callback. This is useful for throttling
2134    /// redrawing operations, and driving animations.
2135    ///
2136    /// When a client is animating on a wl_surface, it can use the 'frame'
2137    /// request to get notified when it is a good time to draw and commit the
2138    /// next frame of animation. If the client commits an update earlier than
2139    /// that, it is likely that some updates will not make it to the display,
2140    /// and the client is wasting resources by drawing too often.
2141    ///
2142    /// The frame request will take effect on the next wl_surface.commit.
2143    /// The notification will only be posted for one frame unless
2144    /// requested again. For a wl_surface, the notifications are posted in
2145    /// the order the frame requests were committed.
2146    ///
2147    /// The server must send the notifications so that a client
2148    /// will not send excessive updates, while still allowing
2149    /// the highest possible update rate for clients that wait for the reply
2150    /// before drawing again. The server should give some time for the client
2151    /// to draw and commit after sending the frame callback events to let it
2152    /// hit the next output refresh.
2153    ///
2154    /// A server should avoid signaling the frame callbacks if the
2155    /// surface is not visible in any way, e.g. the surface is off-screen,
2156    /// or completely obscured by other opaque surfaces.
2157    ///
2158    /// The object returned by this request will be destroyed by the
2159    /// compositor after the callback is fired and as such the client must not
2160    /// attempt to use it after that point.
2161    ///
2162    /// The callback_data passed in the callback is the current time, in
2163    /// milliseconds, with an undefined base.
2164    ///
2165    /// # Arguments
2166    ///
2167    /// - `callback`: callback object for the frame request
2168    #[inline]
2169    fn handle_frame(
2170        &mut self,
2171        slf: &Rc<WlSurface>,
2172        callback: &Rc<WlCallback>,
2173    ) {
2174        if !slf.core.forward_to_server.get() {
2175            return;
2176        }
2177        let res = slf.try_send_frame(
2178            callback,
2179        );
2180        if let Err(e) = res {
2181            log_forward("wl_surface.frame", &e);
2182        }
2183    }
2184
2185    /// set opaque region
2186    ///
2187    /// This request sets the region of the surface that contains
2188    /// opaque content.
2189    ///
2190    /// The opaque region is an optimization hint for the compositor
2191    /// that lets it optimize the redrawing of content behind opaque
2192    /// regions.  Setting an opaque region is not required for correct
2193    /// behaviour, but marking transparent content as opaque will result
2194    /// in repaint artifacts.
2195    ///
2196    /// The opaque region is specified in surface-local coordinates.
2197    ///
2198    /// The compositor ignores the parts of the opaque region that fall
2199    /// outside of the surface.
2200    ///
2201    /// Opaque region is double-buffered state, see wl_surface.commit.
2202    ///
2203    /// wl_surface.set_opaque_region changes the pending opaque region.
2204    /// wl_surface.commit copies the pending region to the current region.
2205    /// Otherwise, the pending and current regions are never changed.
2206    ///
2207    /// The initial value for an opaque region is empty. Setting the pending
2208    /// opaque region has copy semantics, and the wl_region object can be
2209    /// destroyed immediately. A NULL wl_region causes the pending opaque
2210    /// region to be set to empty.
2211    ///
2212    /// # Arguments
2213    ///
2214    /// - `region`: opaque region of the surface
2215    ///
2216    /// All borrowed proxies passed to this function are guaranteed to be
2217    /// immutable and non-null.
2218    #[inline]
2219    fn handle_set_opaque_region(
2220        &mut self,
2221        slf: &Rc<WlSurface>,
2222        region: Option<&Rc<WlRegion>>,
2223    ) {
2224        if !slf.core.forward_to_server.get() {
2225            return;
2226        }
2227        let res = slf.try_send_set_opaque_region(
2228            region,
2229        );
2230        if let Err(e) = res {
2231            log_forward("wl_surface.set_opaque_region", &e);
2232        }
2233    }
2234
2235    /// set input region
2236    ///
2237    /// This request sets the region of the surface that can receive
2238    /// pointer and touch events.
2239    ///
2240    /// Input events happening outside of this region will try the next
2241    /// surface in the server surface stack. The compositor ignores the
2242    /// parts of the input region that fall outside of the surface.
2243    ///
2244    /// The input region is specified in surface-local coordinates.
2245    ///
2246    /// Input region is double-buffered state, see wl_surface.commit.
2247    ///
2248    /// wl_surface.set_input_region changes the pending input region.
2249    /// wl_surface.commit copies the pending region to the current region.
2250    /// Otherwise the pending and current regions are never changed,
2251    /// except cursor and icon surfaces are special cases, see
2252    /// wl_pointer.set_cursor and wl_data_device.start_drag.
2253    ///
2254    /// The initial value for an input region is infinite. That means the
2255    /// whole surface will accept input. Setting the pending input region
2256    /// has copy semantics, and the wl_region object can be destroyed
2257    /// immediately. A NULL wl_region causes the input region to be set
2258    /// to infinite.
2259    ///
2260    /// # Arguments
2261    ///
2262    /// - `region`: input region of the surface
2263    ///
2264    /// All borrowed proxies passed to this function are guaranteed to be
2265    /// immutable and non-null.
2266    #[inline]
2267    fn handle_set_input_region(
2268        &mut self,
2269        slf: &Rc<WlSurface>,
2270        region: Option<&Rc<WlRegion>>,
2271    ) {
2272        if !slf.core.forward_to_server.get() {
2273            return;
2274        }
2275        let res = slf.try_send_set_input_region(
2276            region,
2277        );
2278        if let Err(e) = res {
2279            log_forward("wl_surface.set_input_region", &e);
2280        }
2281    }
2282
2283    /// commit pending surface state
2284    ///
2285    /// Surface state (input, opaque, and damage regions, attached buffers,
2286    /// etc.) is double-buffered. Protocol requests modify the pending state,
2287    /// as opposed to the active state in use by the compositor.
2288    ///
2289    /// A commit request atomically creates a content update from the pending
2290    /// state, even if the pending state has not been touched. The content
2291    /// update is placed in a queue until it becomes active. After commit, the
2292    /// new pending state is as documented for each related request.
2293    ///
2294    /// When the content update is applied, the wl_buffer is applied before all
2295    /// other state. This means that all coordinates in double-buffered state
2296    /// are relative to the newly attached wl_buffers, except for
2297    /// wl_surface.attach itself. If there is no newly attached wl_buffer, the
2298    /// coordinates are relative to the previous content update.
2299    ///
2300    /// All requests that need a commit to become effective are documented
2301    /// to affect double-buffered state.
2302    ///
2303    /// Other interfaces may add further double-buffered surface state.
2304    #[inline]
2305    fn handle_commit(
2306        &mut self,
2307        slf: &Rc<WlSurface>,
2308    ) {
2309        if !slf.core.forward_to_server.get() {
2310            return;
2311        }
2312        let res = slf.try_send_commit(
2313        );
2314        if let Err(e) = res {
2315            log_forward("wl_surface.commit", &e);
2316        }
2317    }
2318
2319    /// surface enters an output
2320    ///
2321    /// This is emitted whenever a surface's creation, movement, or resizing
2322    /// results in some part of it being within the scanout region of an
2323    /// output.
2324    ///
2325    /// Note that a surface may be overlapping with zero or more outputs.
2326    ///
2327    /// # Arguments
2328    ///
2329    /// - `output`: output entered by the surface
2330    ///
2331    /// All borrowed proxies passed to this function are guaranteed to be
2332    /// immutable and non-null.
2333    #[inline]
2334    fn handle_enter(
2335        &mut self,
2336        slf: &Rc<WlSurface>,
2337        output: &Rc<WlOutput>,
2338    ) {
2339        if !slf.core.forward_to_client.get() {
2340            return;
2341        }
2342        if let Some(client_id) = slf.core.client_id.get() {
2343            if let Some(client_id_2) = output.core().client_id.get() {
2344                if client_id != client_id_2 {
2345                    return;
2346                }
2347            }
2348        }
2349        let res = slf.try_send_enter(
2350            output,
2351        );
2352        if let Err(e) = res {
2353            log_forward("wl_surface.enter", &e);
2354        }
2355    }
2356
2357    /// surface leaves an output
2358    ///
2359    /// This is emitted whenever a surface's creation, movement, or resizing
2360    /// results in it no longer having any part of it within the scanout region
2361    /// of an output.
2362    ///
2363    /// Clients should not use the number of outputs the surface is on for frame
2364    /// throttling purposes. The surface might be hidden even if no leave event
2365    /// has been sent, and the compositor might expect new surface content
2366    /// updates even if no enter event has been sent. The frame event should be
2367    /// used instead.
2368    ///
2369    /// # Arguments
2370    ///
2371    /// - `output`: output left by the surface
2372    ///
2373    /// All borrowed proxies passed to this function are guaranteed to be
2374    /// immutable and non-null.
2375    #[inline]
2376    fn handle_leave(
2377        &mut self,
2378        slf: &Rc<WlSurface>,
2379        output: &Rc<WlOutput>,
2380    ) {
2381        if !slf.core.forward_to_client.get() {
2382            return;
2383        }
2384        if let Some(client_id) = slf.core.client_id.get() {
2385            if let Some(client_id_2) = output.core().client_id.get() {
2386                if client_id != client_id_2 {
2387                    return;
2388                }
2389            }
2390        }
2391        let res = slf.try_send_leave(
2392            output,
2393        );
2394        if let Err(e) = res {
2395            log_forward("wl_surface.leave", &e);
2396        }
2397    }
2398
2399    /// sets the buffer transformation
2400    ///
2401    /// This request sets the transformation that the client has already applied
2402    /// to the content of the buffer. The accepted values for the transform
2403    /// parameter are the values for wl_output.transform.
2404    ///
2405    /// The compositor applies the inverse of this transformation whenever it
2406    /// uses the buffer contents.
2407    ///
2408    /// Buffer transform is double-buffered state, see wl_surface.commit.
2409    ///
2410    /// A newly created surface has its buffer transformation set to normal.
2411    ///
2412    /// wl_surface.set_buffer_transform changes the pending buffer
2413    /// transformation. wl_surface.commit copies the pending buffer
2414    /// transformation to the current one. Otherwise, the pending and current
2415    /// values are never changed.
2416    ///
2417    /// The purpose of this request is to allow clients to render content
2418    /// according to the output transform, thus permitting the compositor to
2419    /// use certain optimizations even if the display is rotated. Using
2420    /// hardware overlays and scanning out a client buffer for fullscreen
2421    /// surfaces are examples of such optimizations. Those optimizations are
2422    /// highly dependent on the compositor implementation, so the use of this
2423    /// request should be considered on a case-by-case basis.
2424    ///
2425    /// Note that if the transform value includes 90 or 270 degree rotation,
2426    /// the width of the buffer will become the surface height and the height
2427    /// of the buffer will become the surface width.
2428    ///
2429    /// If transform is not one of the values from the
2430    /// wl_output.transform enum the invalid_transform protocol error
2431    /// is raised.
2432    ///
2433    /// # Arguments
2434    ///
2435    /// - `transform`: transform for interpreting buffer contents
2436    #[inline]
2437    fn handle_set_buffer_transform(
2438        &mut self,
2439        slf: &Rc<WlSurface>,
2440        transform: WlOutputTransform,
2441    ) {
2442        if !slf.core.forward_to_server.get() {
2443            return;
2444        }
2445        let res = slf.try_send_set_buffer_transform(
2446            transform,
2447        );
2448        if let Err(e) = res {
2449            log_forward("wl_surface.set_buffer_transform", &e);
2450        }
2451    }
2452
2453    /// sets the buffer scaling factor
2454    ///
2455    /// This request sets an optional scaling factor on how the compositor
2456    /// interprets the contents of the buffer attached to the window.
2457    ///
2458    /// Buffer scale is double-buffered state, see wl_surface.commit.
2459    ///
2460    /// A newly created surface has its buffer scale set to 1.
2461    ///
2462    /// wl_surface.set_buffer_scale changes the pending buffer scale.
2463    /// wl_surface.commit copies the pending buffer scale to the current one.
2464    /// Otherwise, the pending and current values are never changed.
2465    ///
2466    /// The purpose of this request is to allow clients to supply higher
2467    /// resolution buffer data for use on high resolution outputs. It is
2468    /// intended that you pick the same buffer scale as the scale of the
2469    /// output that the surface is displayed on. This means the compositor
2470    /// can avoid scaling when rendering the surface on that output.
2471    ///
2472    /// Note that if the scale is larger than 1, then you have to attach
2473    /// a buffer that is larger (by a factor of scale in each dimension)
2474    /// than the desired surface size.
2475    ///
2476    /// If scale is not greater than 0 the invalid_scale protocol error is
2477    /// raised.
2478    ///
2479    /// # Arguments
2480    ///
2481    /// - `scale`: scale for interpreting buffer contents
2482    #[inline]
2483    fn handle_set_buffer_scale(
2484        &mut self,
2485        slf: &Rc<WlSurface>,
2486        scale: i32,
2487    ) {
2488        if !slf.core.forward_to_server.get() {
2489            return;
2490        }
2491        let res = slf.try_send_set_buffer_scale(
2492            scale,
2493        );
2494        if let Err(e) = res {
2495            log_forward("wl_surface.set_buffer_scale", &e);
2496        }
2497    }
2498
2499    /// mark part of the surface damaged using buffer coordinates
2500    ///
2501    /// This request is used to describe the regions where the pending
2502    /// buffer is different from the current surface contents, and where
2503    /// the surface therefore needs to be repainted. The compositor
2504    /// ignores the parts of the damage that fall outside of the surface.
2505    ///
2506    /// Damage is double-buffered state, see wl_surface.commit.
2507    ///
2508    /// The damage rectangle is specified in buffer coordinates,
2509    /// where x and y specify the upper left corner of the damage rectangle.
2510    ///
2511    /// The initial value for pending damage is empty: no damage.
2512    /// wl_surface.damage_buffer adds pending damage: the new pending
2513    /// damage is the union of old pending damage and the given rectangle.
2514    ///
2515    /// wl_surface.commit assigns pending damage as the current damage,
2516    /// and clears pending damage. The server will clear the current
2517    /// damage as it repaints the surface.
2518    ///
2519    /// This request differs from wl_surface.damage in only one way - it
2520    /// takes damage in buffer coordinates instead of surface-local
2521    /// coordinates. While this generally is more intuitive than surface
2522    /// coordinates, it is especially desirable when using wp_viewport
2523    /// or when a drawing library (like EGL) is unaware of buffer scale
2524    /// and buffer transform.
2525    ///
2526    /// Note: Because buffer transformation changes and damage requests may
2527    /// be interleaved in the protocol stream, it is impossible to determine
2528    /// the actual mapping between surface and buffer damage until
2529    /// wl_surface.commit time. Therefore, compositors wishing to take both
2530    /// kinds of damage into account will have to accumulate damage from the
2531    /// two requests separately and only transform from one to the other
2532    /// after receiving the wl_surface.commit.
2533    ///
2534    /// # Arguments
2535    ///
2536    /// - `x`: buffer-local x coordinate
2537    /// - `y`: buffer-local y coordinate
2538    /// - `width`: width of damage rectangle
2539    /// - `height`: height of damage rectangle
2540    #[inline]
2541    fn handle_damage_buffer(
2542        &mut self,
2543        slf: &Rc<WlSurface>,
2544        x: i32,
2545        y: i32,
2546        width: i32,
2547        height: i32,
2548    ) {
2549        if !slf.core.forward_to_server.get() {
2550            return;
2551        }
2552        let res = slf.try_send_damage_buffer(
2553            x,
2554            y,
2555            width,
2556            height,
2557        );
2558        if let Err(e) = res {
2559            log_forward("wl_surface.damage_buffer", &e);
2560        }
2561    }
2562
2563    /// set the surface contents offset
2564    ///
2565    /// The x and y arguments specify the location of the new pending
2566    /// buffer's upper left corner, relative to the current buffer's upper
2567    /// left corner, in surface-local coordinates. In other words, the
2568    /// x and y, combined with the new surface size define in which
2569    /// directions the surface's size changes.
2570    ///
2571    /// The exact semantics of wl_surface.offset are role-specific. Refer to
2572    /// the documentation of specific roles for more information.
2573    ///
2574    /// Surface location offset is double-buffered state, see
2575    /// wl_surface.commit.
2576    ///
2577    /// This request is semantically equivalent to and the replaces the x and y
2578    /// arguments in the wl_surface.attach request in wl_surface versions prior
2579    /// to 5. See wl_surface.attach for details.
2580    ///
2581    /// # Arguments
2582    ///
2583    /// - `x`: surface-local x coordinate
2584    /// - `y`: surface-local y coordinate
2585    #[inline]
2586    fn handle_offset(
2587        &mut self,
2588        slf: &Rc<WlSurface>,
2589        x: i32,
2590        y: i32,
2591    ) {
2592        if !slf.core.forward_to_server.get() {
2593            return;
2594        }
2595        let res = slf.try_send_offset(
2596            x,
2597            y,
2598        );
2599        if let Err(e) = res {
2600            log_forward("wl_surface.offset", &e);
2601        }
2602    }
2603
2604    /// preferred buffer scale for the surface
2605    ///
2606    /// This event indicates the preferred buffer scale for this surface. It is
2607    /// sent whenever the compositor's preference changes.
2608    ///
2609    /// Before receiving this event the preferred buffer scale for this surface
2610    /// is 1.
2611    ///
2612    /// It is intended that scaling aware clients use this event to scale their
2613    /// content and use wl_surface.set_buffer_scale to indicate the scale they
2614    /// have rendered with. This allows clients to supply a higher detail
2615    /// buffer.
2616    ///
2617    /// The compositor shall emit a scale value greater than 0.
2618    ///
2619    /// # Arguments
2620    ///
2621    /// - `factor`: preferred scaling factor
2622    #[inline]
2623    fn handle_preferred_buffer_scale(
2624        &mut self,
2625        slf: &Rc<WlSurface>,
2626        factor: i32,
2627    ) {
2628        if !slf.core.forward_to_client.get() {
2629            return;
2630        }
2631        let res = slf.try_send_preferred_buffer_scale(
2632            factor,
2633        );
2634        if let Err(e) = res {
2635            log_forward("wl_surface.preferred_buffer_scale", &e);
2636        }
2637    }
2638
2639    /// preferred buffer transform for the surface
2640    ///
2641    /// This event indicates the preferred buffer transform for this surface.
2642    /// It is sent whenever the compositor's preference changes.
2643    ///
2644    /// Before receiving this event the preferred buffer transform for this
2645    /// surface is normal.
2646    ///
2647    /// Applying this transformation to the surface buffer contents and using
2648    /// wl_surface.set_buffer_transform might allow the compositor to use the
2649    /// surface buffer more efficiently.
2650    ///
2651    /// # Arguments
2652    ///
2653    /// - `transform`: preferred transform
2654    #[inline]
2655    fn handle_preferred_buffer_transform(
2656        &mut self,
2657        slf: &Rc<WlSurface>,
2658        transform: WlOutputTransform,
2659    ) {
2660        if !slf.core.forward_to_client.get() {
2661            return;
2662        }
2663        let res = slf.try_send_preferred_buffer_transform(
2664            transform,
2665        );
2666        if let Err(e) = res {
2667            log_forward("wl_surface.preferred_buffer_transform", &e);
2668        }
2669    }
2670}
2671
2672impl ObjectPrivate for WlSurface {
2673    fn new(state: &Rc<State>, version: u32) -> Rc<Self> {
2674        Rc::<Self>::new_cyclic(|slf| Self {
2675            core: ObjectCore::new(state, slf.clone(), ObjectInterface::WlSurface, version),
2676            handler: Default::default(),
2677        })
2678    }
2679
2680    fn delete_id(self: Rc<Self>) -> Result<(), (ObjectError, Rc<dyn Object>)> {
2681        let Some(mut handler) = self.handler.try_borrow_mut() else {
2682            return Err((ObjectError(ObjectErrorKind::HandlerBorrowed), self));
2683        };
2684        if let Some(handler) = &mut *handler {
2685            handler.delete_id(&self);
2686        } else {
2687            self.core.delete_id();
2688        }
2689        Ok(())
2690    }
2691
2692    fn handle_request(self: Rc<Self>, client: &Rc<Client>, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
2693        let Some(mut handler) = self.handler.try_borrow_mut() else {
2694            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
2695        };
2696        let handler = &mut *handler;
2697        match msg[1] & 0xffff {
2698            0 => {
2699                if msg.len() != 2 {
2700                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
2701                }
2702                #[cfg(feature = "logging")]
2703                if self.core.state.log {
2704                    #[cold]
2705                    fn log(state: &State, client_id: u64, id: u32) {
2706                        let (millis, micros) = time_since_epoch();
2707                        let prefix = &state.log_prefix;
2708                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.destroy()\n", client_id, id);
2709                        state.log(args);
2710                    }
2711                    log(&self.core.state, client.endpoint.id, msg[0]);
2712                }
2713                self.core.handle_client_destroy();
2714                if let Some(handler) = handler {
2715                    (**handler).handle_destroy(&self);
2716                } else {
2717                    DefaultHandler.handle_destroy(&self);
2718                }
2719            }
2720            1 => {
2721                let [
2722                    arg0,
2723                    arg1,
2724                    arg2,
2725                ] = msg[2..] else {
2726                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 20)));
2727                };
2728                let arg1 = arg1 as i32;
2729                let arg2 = arg2 as i32;
2730                #[cfg(feature = "logging")]
2731                if self.core.state.log {
2732                    #[cold]
2733                    fn log(state: &State, client_id: u64, id: u32, arg0: u32, arg1: i32, arg2: i32) {
2734                        let (millis, micros) = time_since_epoch();
2735                        let prefix = &state.log_prefix;
2736                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.attach(buffer: wl_buffer#{}, x: {}, y: {})\n", client_id, id, arg0, arg1, arg2);
2737                        state.log(args);
2738                    }
2739                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2);
2740                }
2741                let arg0 = if arg0 == 0 {
2742                    None
2743                } else {
2744                    let arg0_id = arg0;
2745                    let Some(arg0) = client.endpoint.lookup(arg0_id) else {
2746                        return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg0_id)));
2747                    };
2748                    let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlBuffer>() else {
2749                        let o = client.endpoint.lookup(arg0_id).unwrap();
2750                        return Err(ObjectError(ObjectErrorKind::WrongObjectType("buffer", o.core().interface, ObjectInterface::WlBuffer)));
2751                    };
2752                    Some(arg0)
2753                };
2754                let arg0 = arg0.as_ref();
2755                if let Some(handler) = handler {
2756                    (**handler).handle_attach(&self, arg0, arg1, arg2);
2757                } else {
2758                    DefaultHandler.handle_attach(&self, arg0, arg1, arg2);
2759                }
2760            }
2761            2 => {
2762                let [
2763                    arg0,
2764                    arg1,
2765                    arg2,
2766                    arg3,
2767                ] = msg[2..] else {
2768                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
2769                };
2770                let arg0 = arg0 as i32;
2771                let arg1 = arg1 as i32;
2772                let arg2 = arg2 as i32;
2773                let arg3 = arg3 as i32;
2774                #[cfg(feature = "logging")]
2775                if self.core.state.log {
2776                    #[cold]
2777                    fn log(state: &State, client_id: u64, id: u32, arg0: i32, arg1: i32, arg2: i32, arg3: i32) {
2778                        let (millis, micros) = time_since_epoch();
2779                        let prefix = &state.log_prefix;
2780                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.damage(x: {}, y: {}, width: {}, height: {})\n", client_id, id, arg0, arg1, arg2, arg3);
2781                        state.log(args);
2782                    }
2783                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2, arg3);
2784                }
2785                if let Some(handler) = handler {
2786                    (**handler).handle_damage(&self, arg0, arg1, arg2, arg3);
2787                } else {
2788                    DefaultHandler.handle_damage(&self, arg0, arg1, arg2, arg3);
2789                }
2790            }
2791            3 => {
2792                let [
2793                    arg0,
2794                ] = msg[2..] else {
2795                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2796                };
2797                #[cfg(feature = "logging")]
2798                if self.core.state.log {
2799                    #[cold]
2800                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
2801                        let (millis, micros) = time_since_epoch();
2802                        let prefix = &state.log_prefix;
2803                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.frame(callback: wl_callback#{})\n", client_id, id, arg0);
2804                        state.log(args);
2805                    }
2806                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
2807                }
2808                let arg0_id = arg0;
2809                let arg0 = WlCallback::new(&self.core.state, self.core.version);
2810                arg0.core().set_client_id(client, arg0_id, arg0.clone())
2811                    .map_err(|e| ObjectError(ObjectErrorKind::SetClientId(arg0_id, "callback", e)))?;
2812                let arg0 = &arg0;
2813                if let Some(handler) = handler {
2814                    (**handler).handle_frame(&self, arg0);
2815                } else {
2816                    DefaultHandler.handle_frame(&self, arg0);
2817                }
2818            }
2819            4 => {
2820                let [
2821                    arg0,
2822                ] = msg[2..] else {
2823                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2824                };
2825                #[cfg(feature = "logging")]
2826                if self.core.state.log {
2827                    #[cold]
2828                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
2829                        let (millis, micros) = time_since_epoch();
2830                        let prefix = &state.log_prefix;
2831                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.set_opaque_region(region: wl_region#{})\n", client_id, id, arg0);
2832                        state.log(args);
2833                    }
2834                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
2835                }
2836                let arg0 = if arg0 == 0 {
2837                    None
2838                } else {
2839                    let arg0_id = arg0;
2840                    let Some(arg0) = client.endpoint.lookup(arg0_id) else {
2841                        return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg0_id)));
2842                    };
2843                    let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlRegion>() else {
2844                        let o = client.endpoint.lookup(arg0_id).unwrap();
2845                        return Err(ObjectError(ObjectErrorKind::WrongObjectType("region", o.core().interface, ObjectInterface::WlRegion)));
2846                    };
2847                    Some(arg0)
2848                };
2849                let arg0 = arg0.as_ref();
2850                if let Some(handler) = handler {
2851                    (**handler).handle_set_opaque_region(&self, arg0);
2852                } else {
2853                    DefaultHandler.handle_set_opaque_region(&self, arg0);
2854                }
2855            }
2856            5 => {
2857                let [
2858                    arg0,
2859                ] = msg[2..] else {
2860                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2861                };
2862                #[cfg(feature = "logging")]
2863                if self.core.state.log {
2864                    #[cold]
2865                    fn log(state: &State, client_id: u64, id: u32, arg0: u32) {
2866                        let (millis, micros) = time_since_epoch();
2867                        let prefix = &state.log_prefix;
2868                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.set_input_region(region: wl_region#{})\n", client_id, id, arg0);
2869                        state.log(args);
2870                    }
2871                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
2872                }
2873                let arg0 = if arg0 == 0 {
2874                    None
2875                } else {
2876                    let arg0_id = arg0;
2877                    let Some(arg0) = client.endpoint.lookup(arg0_id) else {
2878                        return Err(ObjectError(ObjectErrorKind::NoClientObject(client.endpoint.id, arg0_id)));
2879                    };
2880                    let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlRegion>() else {
2881                        let o = client.endpoint.lookup(arg0_id).unwrap();
2882                        return Err(ObjectError(ObjectErrorKind::WrongObjectType("region", o.core().interface, ObjectInterface::WlRegion)));
2883                    };
2884                    Some(arg0)
2885                };
2886                let arg0 = arg0.as_ref();
2887                if let Some(handler) = handler {
2888                    (**handler).handle_set_input_region(&self, arg0);
2889                } else {
2890                    DefaultHandler.handle_set_input_region(&self, arg0);
2891                }
2892            }
2893            6 => {
2894                if msg.len() != 2 {
2895                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 8)));
2896                }
2897                #[cfg(feature = "logging")]
2898                if self.core.state.log {
2899                    #[cold]
2900                    fn log(state: &State, client_id: u64, id: u32) {
2901                        let (millis, micros) = time_since_epoch();
2902                        let prefix = &state.log_prefix;
2903                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.commit()\n", client_id, id);
2904                        state.log(args);
2905                    }
2906                    log(&self.core.state, client.endpoint.id, msg[0]);
2907                }
2908                if let Some(handler) = handler {
2909                    (**handler).handle_commit(&self);
2910                } else {
2911                    DefaultHandler.handle_commit(&self);
2912                }
2913            }
2914            7 => {
2915                let [
2916                    arg0,
2917                ] = msg[2..] else {
2918                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2919                };
2920                let arg0 = WlOutputTransform(arg0);
2921                #[cfg(feature = "logging")]
2922                if self.core.state.log {
2923                    #[cold]
2924                    fn log(state: &State, client_id: u64, id: u32, arg0: WlOutputTransform) {
2925                        let (millis, micros) = time_since_epoch();
2926                        let prefix = &state.log_prefix;
2927                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.set_buffer_transform(transform: {:?})\n", client_id, id, arg0);
2928                        state.log(args);
2929                    }
2930                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
2931                }
2932                if let Some(handler) = handler {
2933                    (**handler).handle_set_buffer_transform(&self, arg0);
2934                } else {
2935                    DefaultHandler.handle_set_buffer_transform(&self, arg0);
2936                }
2937            }
2938            8 => {
2939                let [
2940                    arg0,
2941                ] = msg[2..] else {
2942                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
2943                };
2944                let arg0 = arg0 as i32;
2945                #[cfg(feature = "logging")]
2946                if self.core.state.log {
2947                    #[cold]
2948                    fn log(state: &State, client_id: u64, id: u32, arg0: i32) {
2949                        let (millis, micros) = time_since_epoch();
2950                        let prefix = &state.log_prefix;
2951                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.set_buffer_scale(scale: {})\n", client_id, id, arg0);
2952                        state.log(args);
2953                    }
2954                    log(&self.core.state, client.endpoint.id, msg[0], arg0);
2955                }
2956                if let Some(handler) = handler {
2957                    (**handler).handle_set_buffer_scale(&self, arg0);
2958                } else {
2959                    DefaultHandler.handle_set_buffer_scale(&self, arg0);
2960                }
2961            }
2962            9 => {
2963                let [
2964                    arg0,
2965                    arg1,
2966                    arg2,
2967                    arg3,
2968                ] = msg[2..] else {
2969                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 24)));
2970                };
2971                let arg0 = arg0 as i32;
2972                let arg1 = arg1 as i32;
2973                let arg2 = arg2 as i32;
2974                let arg3 = arg3 as i32;
2975                #[cfg(feature = "logging")]
2976                if self.core.state.log {
2977                    #[cold]
2978                    fn log(state: &State, client_id: u64, id: u32, arg0: i32, arg1: i32, arg2: i32, arg3: i32) {
2979                        let (millis, micros) = time_since_epoch();
2980                        let prefix = &state.log_prefix;
2981                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.damage_buffer(x: {}, y: {}, width: {}, height: {})\n", client_id, id, arg0, arg1, arg2, arg3);
2982                        state.log(args);
2983                    }
2984                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1, arg2, arg3);
2985                }
2986                if let Some(handler) = handler {
2987                    (**handler).handle_damage_buffer(&self, arg0, arg1, arg2, arg3);
2988                } else {
2989                    DefaultHandler.handle_damage_buffer(&self, arg0, arg1, arg2, arg3);
2990                }
2991            }
2992            10 => {
2993                let [
2994                    arg0,
2995                    arg1,
2996                ] = msg[2..] else {
2997                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 16)));
2998                };
2999                let arg0 = arg0 as i32;
3000                let arg1 = arg1 as i32;
3001                #[cfg(feature = "logging")]
3002                if self.core.state.log {
3003                    #[cold]
3004                    fn log(state: &State, client_id: u64, id: u32, arg0: i32, arg1: i32) {
3005                        let (millis, micros) = time_since_epoch();
3006                        let prefix = &state.log_prefix;
3007                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}client#{:<4} -> wl_surface#{}.offset(x: {}, y: {})\n", client_id, id, arg0, arg1);
3008                        state.log(args);
3009                    }
3010                    log(&self.core.state, client.endpoint.id, msg[0], arg0, arg1);
3011                }
3012                if let Some(handler) = handler {
3013                    (**handler).handle_offset(&self, arg0, arg1);
3014                } else {
3015                    DefaultHandler.handle_offset(&self, arg0, arg1);
3016                }
3017            }
3018            n => {
3019                let _ = client;
3020                let _ = msg;
3021                let _ = fds;
3022                let _ = handler;
3023                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
3024            }
3025        }
3026        Ok(())
3027    }
3028
3029    fn handle_event(self: Rc<Self>, server: &Endpoint, msg: &[u32], fds: &mut VecDeque<Rc<OwnedFd>>) -> Result<(), ObjectError> {
3030        let Some(mut handler) = self.handler.try_borrow_mut() else {
3031            return Err(ObjectError(ObjectErrorKind::HandlerBorrowed));
3032        };
3033        let handler = &mut *handler;
3034        match msg[1] & 0xffff {
3035            0 => {
3036                let [
3037                    arg0,
3038                ] = msg[2..] else {
3039                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
3040                };
3041                #[cfg(feature = "logging")]
3042                if self.core.state.log {
3043                    #[cold]
3044                    fn log(state: &State, id: u32, arg0: u32) {
3045                        let (millis, micros) = time_since_epoch();
3046                        let prefix = &state.log_prefix;
3047                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_surface#{}.enter(output: wl_output#{})\n", id, arg0);
3048                        state.log(args);
3049                    }
3050                    log(&self.core.state, msg[0], arg0);
3051                }
3052                let arg0_id = arg0;
3053                let Some(arg0) = server.lookup(arg0_id) else {
3054                    return Err(ObjectError(ObjectErrorKind::NoServerObject(arg0_id)));
3055                };
3056                let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlOutput>() else {
3057                    let o = server.lookup(arg0_id).unwrap();
3058                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("output", o.core().interface, ObjectInterface::WlOutput)));
3059                };
3060                let arg0 = &arg0;
3061                if let Some(handler) = handler {
3062                    (**handler).handle_enter(&self, arg0);
3063                } else {
3064                    DefaultHandler.handle_enter(&self, arg0);
3065                }
3066            }
3067            1 => {
3068                let [
3069                    arg0,
3070                ] = msg[2..] else {
3071                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
3072                };
3073                #[cfg(feature = "logging")]
3074                if self.core.state.log {
3075                    #[cold]
3076                    fn log(state: &State, id: u32, arg0: u32) {
3077                        let (millis, micros) = time_since_epoch();
3078                        let prefix = &state.log_prefix;
3079                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_surface#{}.leave(output: wl_output#{})\n", id, arg0);
3080                        state.log(args);
3081                    }
3082                    log(&self.core.state, msg[0], arg0);
3083                }
3084                let arg0_id = arg0;
3085                let Some(arg0) = server.lookup(arg0_id) else {
3086                    return Err(ObjectError(ObjectErrorKind::NoServerObject(arg0_id)));
3087                };
3088                let Ok(arg0) = (arg0 as Rc<dyn Any>).downcast::<WlOutput>() else {
3089                    let o = server.lookup(arg0_id).unwrap();
3090                    return Err(ObjectError(ObjectErrorKind::WrongObjectType("output", o.core().interface, ObjectInterface::WlOutput)));
3091                };
3092                let arg0 = &arg0;
3093                if let Some(handler) = handler {
3094                    (**handler).handle_leave(&self, arg0);
3095                } else {
3096                    DefaultHandler.handle_leave(&self, arg0);
3097                }
3098            }
3099            2 => {
3100                let [
3101                    arg0,
3102                ] = msg[2..] else {
3103                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
3104                };
3105                let arg0 = arg0 as i32;
3106                #[cfg(feature = "logging")]
3107                if self.core.state.log {
3108                    #[cold]
3109                    fn log(state: &State, id: u32, arg0: i32) {
3110                        let (millis, micros) = time_since_epoch();
3111                        let prefix = &state.log_prefix;
3112                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_surface#{}.preferred_buffer_scale(factor: {})\n", id, arg0);
3113                        state.log(args);
3114                    }
3115                    log(&self.core.state, msg[0], arg0);
3116                }
3117                if let Some(handler) = handler {
3118                    (**handler).handle_preferred_buffer_scale(&self, arg0);
3119                } else {
3120                    DefaultHandler.handle_preferred_buffer_scale(&self, arg0);
3121                }
3122            }
3123            3 => {
3124                let [
3125                    arg0,
3126                ] = msg[2..] else {
3127                    return Err(ObjectError(ObjectErrorKind::WrongMessageSize(msg.len() as u32 * 4, 12)));
3128                };
3129                let arg0 = WlOutputTransform(arg0);
3130                #[cfg(feature = "logging")]
3131                if self.core.state.log {
3132                    #[cold]
3133                    fn log(state: &State, id: u32, arg0: WlOutputTransform) {
3134                        let (millis, micros) = time_since_epoch();
3135                        let prefix = &state.log_prefix;
3136                        let args = format_args!("[{millis:7}.{micros:03}] {prefix}server      -> wl_surface#{}.preferred_buffer_transform(transform: {:?})\n", id, arg0);
3137                        state.log(args);
3138                    }
3139                    log(&self.core.state, msg[0], arg0);
3140                }
3141                if let Some(handler) = handler {
3142                    (**handler).handle_preferred_buffer_transform(&self, arg0);
3143                } else {
3144                    DefaultHandler.handle_preferred_buffer_transform(&self, arg0);
3145                }
3146            }
3147            n => {
3148                let _ = server;
3149                let _ = msg;
3150                let _ = fds;
3151                let _ = handler;
3152                return Err(ObjectError(ObjectErrorKind::UnknownMessageId(n)));
3153            }
3154        }
3155        Ok(())
3156    }
3157
3158    fn get_request_name(&self, id: u32) -> Option<&'static str> {
3159        let name = match id {
3160            0 => "destroy",
3161            1 => "attach",
3162            2 => "damage",
3163            3 => "frame",
3164            4 => "set_opaque_region",
3165            5 => "set_input_region",
3166            6 => "commit",
3167            7 => "set_buffer_transform",
3168            8 => "set_buffer_scale",
3169            9 => "damage_buffer",
3170            10 => "offset",
3171            _ => return None,
3172        };
3173        Some(name)
3174    }
3175
3176    fn get_event_name(&self, id: u32) -> Option<&'static str> {
3177        let name = match id {
3178            0 => "enter",
3179            1 => "leave",
3180            2 => "preferred_buffer_scale",
3181            3 => "preferred_buffer_transform",
3182            _ => return None,
3183        };
3184        Some(name)
3185    }
3186}
3187
3188impl Object for WlSurface {
3189    fn core(&self) -> &ObjectCore {
3190        &self.core
3191    }
3192
3193    fn unset_handler(&self) {
3194        self.handler.set(None);
3195    }
3196
3197    fn get_handler_any_ref(&self) -> Result<HandlerRef<'_, dyn Any>, HandlerAccessError> {
3198        let borrowed = self.handler.try_borrow().ok_or(HandlerAccessError::AlreadyBorrowed)?;
3199        if borrowed.is_none() {
3200            return Err(HandlerAccessError::NoHandler);
3201        }
3202        Ok(HandlerRef::map(borrowed, |handler| &**handler.as_ref().unwrap() as &dyn Any))
3203    }
3204
3205    fn get_handler_any_mut(&self) -> Result<HandlerMut<'_, dyn Any>, HandlerAccessError> {
3206        let borrowed = self.handler.try_borrow_mut().ok_or(HandlerAccessError::AlreadyBorrowed)?;
3207        if borrowed.is_none() {
3208            return Err(HandlerAccessError::NoHandler);
3209        }
3210        Ok(HandlerMut::map(borrowed, |handler| &mut **handler.as_mut().unwrap() as &mut dyn Any))
3211    }
3212}
3213
3214impl WlSurface {
3215    /// Since when the error.invalid_scale enum variant is available.
3216    pub const ENM__ERROR_INVALID_SCALE__SINCE: u32 = 1;
3217    /// Since when the error.invalid_transform enum variant is available.
3218    pub const ENM__ERROR_INVALID_TRANSFORM__SINCE: u32 = 1;
3219    /// Since when the error.invalid_size enum variant is available.
3220    pub const ENM__ERROR_INVALID_SIZE__SINCE: u32 = 1;
3221    /// Since when the error.invalid_offset enum variant is available.
3222    pub const ENM__ERROR_INVALID_OFFSET__SINCE: u32 = 1;
3223    /// Since when the error.defunct_role_object enum variant is available.
3224    pub const ENM__ERROR_DEFUNCT_ROLE_OBJECT__SINCE: u32 = 1;
3225}
3226
3227/// wl_surface error values
3228///
3229/// These errors can be emitted in response to wl_surface requests.
3230#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
3231pub struct WlSurfaceError(pub u32);
3232
3233impl WlSurfaceError {
3234    /// buffer scale value is invalid
3235    pub const INVALID_SCALE: Self = Self(0);
3236
3237    /// buffer transform value is invalid
3238    pub const INVALID_TRANSFORM: Self = Self(1);
3239
3240    /// buffer size is invalid
3241    pub const INVALID_SIZE: Self = Self(2);
3242
3243    /// buffer offset is invalid
3244    pub const INVALID_OFFSET: Self = Self(3);
3245
3246    /// surface was destroyed before its role object
3247    pub const DEFUNCT_ROLE_OBJECT: Self = Self(4);
3248}
3249
3250impl Debug for WlSurfaceError {
3251    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
3252        let name = match *self {
3253            Self::INVALID_SCALE => "INVALID_SCALE",
3254            Self::INVALID_TRANSFORM => "INVALID_TRANSFORM",
3255            Self::INVALID_SIZE => "INVALID_SIZE",
3256            Self::INVALID_OFFSET => "INVALID_OFFSET",
3257            Self::DEFUNCT_ROLE_OBJECT => "DEFUNCT_ROLE_OBJECT",
3258            _ => return Debug::fmt(&self.0, f),
3259        };
3260        f.write_str(name)
3261    }
3262}