simple_window/common/protocols_data/wayland/
wl_output.rs

1//! compositor output region
2//!
3//! An output describes part of the compositor geometry.  The
4//! compositor works in the 'compositor coordinate system' and an
5//! output corresponds to a rectangular area in that space that is
6//! actually visible.  This typically corresponds to a monitor that
7//! displays part of the compositor space.  This object is published
8//! as global during start up, or when a monitor is hotplugged.
9
10use {super::super::all_types::*, ::wl_client::builder::prelude::*};
11
12static INTERFACE: wl_interface = wl_interface {
13    name: c"wl_output".as_ptr(),
14    version: 4,
15    method_count: 1,
16    methods: {
17        static MESSAGES: [wl_message; 1] = [wl_message {
18            name: c"release".as_ptr(),
19            signature: c"".as_ptr(),
20            types: {
21                static TYPES: [Option<&'static wl_interface>; 0] = [];
22                TYPES.as_ptr().cast()
23            },
24        }];
25        MESSAGES.as_ptr()
26    },
27    event_count: 6,
28    events: {
29        static MESSAGES: [wl_message; 6] = [
30            wl_message {
31                name: c"geometry".as_ptr(),
32                signature: c"iiiiissi".as_ptr(),
33                types: {
34                    static TYPES: [Option<&'static wl_interface>; 8] =
35                        [None, None, None, None, None, None, None, None];
36                    TYPES.as_ptr().cast()
37                },
38            },
39            wl_message {
40                name: c"mode".as_ptr(),
41                signature: c"uiii".as_ptr(),
42                types: {
43                    static TYPES: [Option<&'static wl_interface>; 4] = [None, None, None, None];
44                    TYPES.as_ptr().cast()
45                },
46            },
47            wl_message {
48                name: c"done".as_ptr(),
49                signature: c"".as_ptr(),
50                types: {
51                    static TYPES: [Option<&'static wl_interface>; 0] = [];
52                    TYPES.as_ptr().cast()
53                },
54            },
55            wl_message {
56                name: c"scale".as_ptr(),
57                signature: c"i".as_ptr(),
58                types: {
59                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
60                    TYPES.as_ptr().cast()
61                },
62            },
63            wl_message {
64                name: c"name".as_ptr(),
65                signature: c"s".as_ptr(),
66                types: {
67                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
68                    TYPES.as_ptr().cast()
69                },
70            },
71            wl_message {
72                name: c"description".as_ptr(),
73                signature: c"s".as_ptr(),
74                types: {
75                    static TYPES: [Option<&'static wl_interface>; 1] = [None];
76                    TYPES.as_ptr().cast()
77                },
78            },
79        ];
80        MESSAGES.as_ptr()
81    },
82};
83
84/// An owned wl_output proxy.
85///
86/// See the documentation of [the module][self] for the interface description.
87#[derive(Clone, Eq, PartialEq)]
88#[repr(transparent)]
89pub struct WlOutput {
90    /// This proxy has the interface INTERFACE.
91    proxy: UntypedOwnedProxy,
92}
93
94/// A borrowed wl_output proxy.
95///
96/// See the documentation of [the module][self] for the interface description.
97#[derive(Eq, PartialEq)]
98#[repr(transparent)]
99pub struct WlOutputRef {
100    /// This proxy has the interface INTERFACE.
101    proxy: UntypedBorrowedProxy,
102}
103
104// SAFETY: WlOutput is a transparent wrapper around UntypedOwnedProxy
105unsafe impl UntypedOwnedProxyWrapper for WlOutput {}
106
107// SAFETY: - INTERFACE is a valid wl_interface
108//         - The only invariant is that self.proxy has a compatible interface
109unsafe impl OwnedProxy for WlOutput {
110    const INTERFACE: &'static str = "wl_output";
111    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
112    const NO_OP_EVENT_HANDLER: Self::NoOpEventHandler =
113        private::EventHandler(private::NoOpEventHandler);
114    const MAX_VERSION: u32 = 4;
115
116    type Borrowed = WlOutputRef;
117    type Api = private::ProxyApi;
118    type NoOpEventHandler = private::EventHandler<private::NoOpEventHandler>;
119}
120
121// SAFETY: WlOutputRef is a transparent wrapper around UntypedBorrowedProxy
122unsafe impl UntypedBorrowedProxyWrapper for WlOutputRef {}
123
124// SAFETY: - The only invariant is that self.proxy has a compatible interface
125unsafe impl BorrowedProxy for WlOutputRef {
126    type Owned = WlOutput;
127}
128
129impl Deref for WlOutput {
130    type Target = WlOutputRef;
131
132    fn deref(&self) -> &Self::Target {
133        proxy::low_level::deref(self)
134    }
135}
136
137mod private {
138    pub struct ProxyApi;
139
140    #[allow(dead_code)]
141    pub struct EventHandler<H>(pub(super) H);
142
143    #[allow(dead_code)]
144    pub struct NoOpEventHandler;
145}
146
147impl Debug for WlOutput {
148    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
149        write!(f, "wl_output#{}", self.proxy.id())
150    }
151}
152
153impl Debug for WlOutputRef {
154    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
155        write!(f, "wl_output#{}", self.proxy.id())
156    }
157}
158
159impl PartialEq<WlOutputRef> for WlOutput {
160    fn eq(&self, other: &WlOutputRef) -> bool {
161        self.proxy == other.proxy
162    }
163}
164
165impl PartialEq<WlOutput> for WlOutputRef {
166    fn eq(&self, other: &WlOutput) -> bool {
167        self.proxy == other.proxy
168    }
169}
170
171#[allow(dead_code)]
172impl WlOutput {
173    /// Since when the release request is available.
174    #[allow(dead_code)]
175    pub const REQ__RELEASE__SINCE: u32 = 3;
176
177    /// release the output object
178    ///
179    /// Using this request a client can tell the server that it is not going to
180    /// use the output object anymore.
181    #[inline]
182    pub fn release(&self) {
183        let mut args = [];
184        // SAFETY: - self.proxy has the interface INTERFACE
185        //         - 0 < INTERFACE.method_count = 1
186        //         - the request signature is ``
187        unsafe {
188            self.proxy.send_destructor(0, &mut args);
189        }
190    }
191}
192
193impl WlOutput {
194    /// Since when the geometry event is available.
195    #[allow(dead_code)]
196    pub const EVT__GEOMETRY__SINCE: u32 = 1;
197
198    /// Since when the mode event is available.
199    #[allow(dead_code)]
200    pub const EVT__MODE__SINCE: u32 = 1;
201
202    /// Since when the done event is available.
203    #[allow(dead_code)]
204    pub const EVT__DONE__SINCE: u32 = 2;
205
206    /// Since when the scale event is available.
207    #[allow(dead_code)]
208    pub const EVT__SCALE__SINCE: u32 = 2;
209
210    /// Since when the name event is available.
211    #[allow(dead_code)]
212    pub const EVT__NAME__SINCE: u32 = 4;
213
214    /// Since when the description event is available.
215    #[allow(dead_code)]
216    pub const EVT__DESCRIPTION__SINCE: u32 = 4;
217}
218
219/// An event handler for [WlOutput] proxies.
220#[allow(dead_code)]
221pub trait WlOutputEventHandler {
222    type Data: 'static;
223
224    /// properties of the output
225    ///
226    /// The geometry event describes geometric properties of the output.
227    /// The event is sent when binding to the output object and whenever
228    /// any of the properties change.
229    ///
230    /// The physical size can be set to zero if it doesn't make sense for this
231    /// output (e.g. for projectors or virtual outputs).
232    ///
233    /// The geometry event will be followed by a done event (starting from
234    /// version 2).
235    ///
236    /// Clients should use wl_surface.preferred_buffer_transform instead of the
237    /// transform advertised by this event to find the preferred buffer
238    /// transform to use for a surface.
239    ///
240    /// Note: wl_output only advertises partial information about the output
241    /// position and identification. Some compositors, for instance those not
242    /// implementing a desktop-style output layout or those exposing virtual
243    /// outputs, might fake this information. Instead of using x and y, clients
244    /// should use xdg_output.logical_position. Instead of using make and model,
245    /// clients should use name and description.
246    ///
247    /// # Arguments
248    ///
249    /// - `x`: x position within the global compositor space
250    /// - `y`: y position within the global compositor space
251    /// - `physical_width`: width in millimeters of the output
252    /// - `physical_height`: height in millimeters of the output
253    /// - `subpixel`: subpixel orientation of the output
254    /// - `make`: textual description of the manufacturer
255    /// - `model`: textual description of the model
256    /// - `transform`: additional transformation applied to buffer contents during presentation
257    #[inline]
258    fn geometry(
259        &self,
260        _data: &mut Self::Data,
261        _slf: &WlOutputRef,
262        x: i32,
263        y: i32,
264        physical_width: i32,
265        physical_height: i32,
266        subpixel: WlOutputSubpixel,
267        make: &str,
268        model: &str,
269        transform: WlOutputTransform,
270    ) {
271        let _ = x;
272        let _ = y;
273        let _ = physical_width;
274        let _ = physical_height;
275        let _ = subpixel;
276        let _ = make;
277        let _ = model;
278        let _ = transform;
279    }
280
281    /// advertise available modes for the output
282    ///
283    /// The mode event describes an available mode for the output.
284    ///
285    /// The event is sent when binding to the output object and there
286    /// will always be one mode, the current mode.  The event is sent
287    /// again if an output changes mode, for the mode that is now
288    /// current.  In other words, the current mode is always the last
289    /// mode that was received with the current flag set.
290    ///
291    /// Non-current modes are deprecated. A compositor can decide to only
292    /// advertise the current mode and never send other modes. Clients
293    /// should not rely on non-current modes.
294    ///
295    /// The size of a mode is given in physical hardware units of
296    /// the output device. This is not necessarily the same as
297    /// the output size in the global compositor space. For instance,
298    /// the output may be scaled, as described in wl_output.scale,
299    /// or transformed, as described in wl_output.transform. Clients
300    /// willing to retrieve the output size in the global compositor
301    /// space should use xdg_output.logical_size instead.
302    ///
303    /// The vertical refresh rate can be set to zero if it doesn't make
304    /// sense for this output (e.g. for virtual outputs).
305    ///
306    /// The mode event will be followed by a done event (starting from
307    /// version 2).
308    ///
309    /// Clients should not use the refresh rate to schedule frames. Instead,
310    /// they should use the wl_surface.frame event or the presentation-time
311    /// protocol.
312    ///
313    /// Note: this information is not always meaningful for all outputs. Some
314    /// compositors, such as those exposing virtual outputs, might fake the
315    /// refresh rate or the size.
316    ///
317    /// # Arguments
318    ///
319    /// - `flags`: bitfield of mode flags
320    /// - `width`: width of the mode in hardware units
321    /// - `height`: height of the mode in hardware units
322    /// - `refresh`: vertical refresh rate in mHz
323    #[inline]
324    fn mode(
325        &self,
326        _data: &mut Self::Data,
327        _slf: &WlOutputRef,
328        flags: WlOutputMode,
329        width: i32,
330        height: i32,
331        refresh: i32,
332    ) {
333        let _ = flags;
334        let _ = width;
335        let _ = height;
336        let _ = refresh;
337    }
338
339    /// sent all information about output
340    ///
341    /// This event is sent after all other properties have been
342    /// sent after binding to the output object and after any
343    /// other property changes done after that. This allows
344    /// changes to the output properties to be seen as
345    /// atomic, even if they happen via multiple events.
346    #[inline]
347    fn done(&self, _data: &mut Self::Data, _slf: &WlOutputRef) {}
348
349    /// output scaling properties
350    ///
351    /// This event contains scaling geometry information
352    /// that is not in the geometry event. It may be sent after
353    /// binding the output object or if the output scale changes
354    /// later. The compositor will emit a non-zero, positive
355    /// value for scale. If it is not sent, the client should
356    /// assume a scale of 1.
357    ///
358    /// A scale larger than 1 means that the compositor will
359    /// automatically scale surface buffers by this amount
360    /// when rendering. This is used for very high resolution
361    /// displays where applications rendering at the native
362    /// resolution would be too small to be legible.
363    ///
364    /// Clients should use wl_surface.preferred_buffer_scale
365    /// instead of this event to find the preferred buffer
366    /// scale to use for a surface.
367    ///
368    /// The scale event will be followed by a done event.
369    ///
370    /// # Arguments
371    ///
372    /// - `factor`: scaling factor of output
373    #[inline]
374    fn scale(&self, _data: &mut Self::Data, _slf: &WlOutputRef, factor: i32) {
375        let _ = factor;
376    }
377
378    /// name of this output
379    ///
380    /// Many compositors will assign user-friendly names to their outputs, show
381    /// them to the user, allow the user to refer to an output, etc. The client
382    /// may wish to know this name as well to offer the user similar behaviors.
383    ///
384    /// The name is a UTF-8 string with no convention defined for its contents.
385    /// Each name is unique among all wl_output globals. The name is only
386    /// guaranteed to be unique for the compositor instance.
387    ///
388    /// The same output name is used for all clients for a given wl_output
389    /// global. Thus, the name can be shared across processes to refer to a
390    /// specific wl_output global.
391    ///
392    /// The name is not guaranteed to be persistent across sessions, thus cannot
393    /// be used to reliably identify an output in e.g. configuration files.
394    ///
395    /// Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
396    /// not assume that the name is a reflection of an underlying DRM connector,
397    /// X11 connection, etc.
398    ///
399    /// The name event is sent after binding the output object. This event is
400    /// only sent once per output object, and the name does not change over the
401    /// lifetime of the wl_output global.
402    ///
403    /// Compositors may re-use the same output name if the wl_output global is
404    /// destroyed and re-created later. Compositors should avoid re-using the
405    /// same name if possible.
406    ///
407    /// The name event will be followed by a done event.
408    ///
409    /// # Arguments
410    ///
411    /// - `name`: output name
412    #[inline]
413    fn name(&self, _data: &mut Self::Data, _slf: &WlOutputRef, name: &str) {
414        let _ = name;
415    }
416
417    /// human-readable description of this output
418    ///
419    /// Many compositors can produce human-readable descriptions of their
420    /// outputs. The client may wish to know this description as well, e.g. for
421    /// output selection purposes.
422    ///
423    /// The description is a UTF-8 string with no convention defined for its
424    /// contents. The description is not guaranteed to be unique among all
425    /// wl_output globals. Examples might include 'Foocorp 11" Display' or
426    /// 'Virtual X11 output via :1'.
427    ///
428    /// The description event is sent after binding the output object and
429    /// whenever the description changes. The description is optional, and may
430    /// not be sent at all.
431    ///
432    /// The description event will be followed by a done event.
433    ///
434    /// # Arguments
435    ///
436    /// - `description`: output description
437    #[inline]
438    fn description(&self, _data: &mut Self::Data, _slf: &WlOutputRef, description: &str) {
439        let _ = description;
440    }
441}
442
443impl WlOutputEventHandler for private::NoOpEventHandler {
444    type Data = ();
445}
446
447// SAFETY: - INTERFACE is a valid wl_interface
448//         - mutable_type always returns the same value
449unsafe impl<H> EventHandler for private::EventHandler<H>
450where
451    H: WlOutputEventHandler,
452{
453    const WL_INTERFACE: &'static wl_interface = &INTERFACE;
454
455    #[inline]
456    fn mutable_type() -> Option<(TypeId, &'static str)> {
457        let id = TypeId::of::<H::Data>();
458        let name = std::any::type_name::<H::Data>();
459        Some((id, name))
460    }
461
462    #[allow(unused_variables)]
463    unsafe fn handle_event(
464        &self,
465        queue: &Queue,
466        data: *mut u8,
467        slf: &UntypedBorrowedProxy,
468        opcode: u32,
469        args: *mut wl_argument,
470    ) {
471        // SAFETY: This function requires that slf has the interface INTERFACE
472        let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlOutputRef>(slf) };
473        // SAFETY: This function requires that data is `&mut T` where `T`
474        //         has the type id returned by `Self::mutable_type`, i.e.,
475        //         `T = H::Data`.
476        let data: &mut H::Data = unsafe { &mut *data.cast() };
477        match opcode {
478            0 => {
479                // SAFETY: INTERFACE requires that there are 8 arguments
480                let args = unsafe { &*args.cast::<[wl_argument; 8]>() };
481                // SAFETY: - INTERFACE requires that args[0] contains an int
482                let arg0 = unsafe { args[0].i };
483                // SAFETY: - INTERFACE requires that args[1] contains an int
484                let arg1 = unsafe { args[1].i };
485                // SAFETY: - INTERFACE requires that args[2] contains an int
486                let arg2 = unsafe { args[2].i };
487                // SAFETY: - INTERFACE requires that args[3] contains an int
488                let arg3 = unsafe { args[3].i };
489                // SAFETY: - INTERFACE requires that args[4] contains an int
490                let arg4 = unsafe { WlOutputSubpixel(args[4].u) };
491                // SAFETY: - INTERFACE requires that args[5] contains a string
492                //         - if the pointer is not null, then it is a c string
493                let arg5 = unsafe { convert_string_arg("wl_output", "make", args[5].s) };
494                // SAFETY: - INTERFACE requires that args[6] contains a string
495                //         - if the pointer is not null, then it is a c string
496                let arg6 = unsafe { convert_string_arg("wl_output", "model", args[6].s) };
497                // SAFETY: - INTERFACE requires that args[7] contains an int
498                let arg7 = unsafe { WlOutputTransform(args[7].u) };
499                self.0
500                    .geometry(data, slf, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
501            }
502            1 => {
503                // SAFETY: INTERFACE requires that there are 4 arguments
504                let args = unsafe { &*args.cast::<[wl_argument; 4]>() };
505                // SAFETY: - INTERFACE requires that args[0] contains a uint
506                let arg0 = unsafe { WlOutputMode(args[0].u) };
507                // SAFETY: - INTERFACE requires that args[1] contains an int
508                let arg1 = unsafe { args[1].i };
509                // SAFETY: - INTERFACE requires that args[2] contains an int
510                let arg2 = unsafe { args[2].i };
511                // SAFETY: - INTERFACE requires that args[3] contains an int
512                let arg3 = unsafe { args[3].i };
513                self.0.mode(data, slf, arg0, arg1, arg2, arg3);
514            }
515            2 => {
516                self.0.done(data, slf);
517            }
518            3 => {
519                // SAFETY: INTERFACE requires that there are 1 arguments
520                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
521                // SAFETY: - INTERFACE requires that args[0] contains an int
522                let arg0 = unsafe { args[0].i };
523                self.0.scale(data, slf, arg0);
524            }
525            4 => {
526                // SAFETY: INTERFACE requires that there are 1 arguments
527                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
528                // SAFETY: - INTERFACE requires that args[0] contains a string
529                //         - if the pointer is not null, then it is a c string
530                let arg0 = unsafe { convert_string_arg("wl_output", "name", args[0].s) };
531                self.0.name(data, slf, arg0);
532            }
533            5 => {
534                // SAFETY: INTERFACE requires that there are 1 arguments
535                let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
536                // SAFETY: - INTERFACE requires that args[0] contains a string
537                //         - if the pointer is not null, then it is a c string
538                let arg0 = unsafe { convert_string_arg("wl_output", "description", args[0].s) };
539                self.0.description(data, slf, arg0);
540            }
541            _ => {
542                invalid_opcode("wl_output", opcode);
543            }
544        }
545    }
546}
547
548impl<H> CreateEventHandler<H> for private::ProxyApi
549where
550    H: WlOutputEventHandler,
551{
552    type EventHandler = private::EventHandler<H>;
553
554    #[inline]
555    fn create_event_handler(handler: H) -> Self::EventHandler {
556        private::EventHandler(handler)
557    }
558}
559
560impl WlOutput {
561    /// Since when the subpixel.unknown enum variant is available.
562    #[allow(dead_code)]
563    pub const ENM__SUBPIXEL_UNKNOWN__SINCE: u32 = 1;
564    /// Since when the subpixel.none enum variant is available.
565    #[allow(dead_code)]
566    pub const ENM__SUBPIXEL_NONE__SINCE: u32 = 1;
567    /// Since when the subpixel.horizontal_rgb enum variant is available.
568    #[allow(dead_code)]
569    pub const ENM__SUBPIXEL_HORIZONTAL_RGB__SINCE: u32 = 1;
570    /// Since when the subpixel.horizontal_bgr enum variant is available.
571    #[allow(dead_code)]
572    pub const ENM__SUBPIXEL_HORIZONTAL_BGR__SINCE: u32 = 1;
573    /// Since when the subpixel.vertical_rgb enum variant is available.
574    #[allow(dead_code)]
575    pub const ENM__SUBPIXEL_VERTICAL_RGB__SINCE: u32 = 1;
576    /// Since when the subpixel.vertical_bgr enum variant is available.
577    #[allow(dead_code)]
578    pub const ENM__SUBPIXEL_VERTICAL_BGR__SINCE: u32 = 1;
579
580    /// Since when the transform.normal enum variant is available.
581    #[allow(dead_code)]
582    pub const ENM__TRANSFORM_NORMAL__SINCE: u32 = 1;
583    /// Since when the transform.90 enum variant is available.
584    #[allow(dead_code)]
585    pub const ENM__TRANSFORM_90__SINCE: u32 = 1;
586    /// Since when the transform.180 enum variant is available.
587    #[allow(dead_code)]
588    pub const ENM__TRANSFORM_180__SINCE: u32 = 1;
589    /// Since when the transform.270 enum variant is available.
590    #[allow(dead_code)]
591    pub const ENM__TRANSFORM_270__SINCE: u32 = 1;
592    /// Since when the transform.flipped enum variant is available.
593    #[allow(dead_code)]
594    pub const ENM__TRANSFORM_FLIPPED__SINCE: u32 = 1;
595    /// Since when the transform.flipped_90 enum variant is available.
596    #[allow(dead_code)]
597    pub const ENM__TRANSFORM_FLIPPED_90__SINCE: u32 = 1;
598    /// Since when the transform.flipped_180 enum variant is available.
599    #[allow(dead_code)]
600    pub const ENM__TRANSFORM_FLIPPED_180__SINCE: u32 = 1;
601    /// Since when the transform.flipped_270 enum variant is available.
602    #[allow(dead_code)]
603    pub const ENM__TRANSFORM_FLIPPED_270__SINCE: u32 = 1;
604
605    /// Since when the mode.current enum variant is available.
606    #[allow(dead_code)]
607    pub const ENM__MODE_CURRENT__SINCE: u32 = 1;
608    /// Since when the mode.preferred enum variant is available.
609    #[allow(dead_code)]
610    pub const ENM__MODE_PREFERRED__SINCE: u32 = 1;
611}
612
613/// subpixel geometry information
614///
615/// This enumeration describes how the physical
616/// pixels on an output are laid out.
617#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
618#[allow(dead_code)]
619pub struct WlOutputSubpixel(pub u32);
620
621impl WlOutputSubpixel {
622    /// unknown geometry
623    #[allow(dead_code)]
624    pub const UNKNOWN: Self = Self(0);
625
626    /// no geometry
627    #[allow(dead_code)]
628    pub const NONE: Self = Self(1);
629
630    /// horizontal RGB
631    #[allow(dead_code)]
632    pub const HORIZONTAL_RGB: Self = Self(2);
633
634    /// horizontal BGR
635    #[allow(dead_code)]
636    pub const HORIZONTAL_BGR: Self = Self(3);
637
638    /// vertical RGB
639    #[allow(dead_code)]
640    pub const VERTICAL_RGB: Self = Self(4);
641
642    /// vertical BGR
643    #[allow(dead_code)]
644    pub const VERTICAL_BGR: Self = Self(5);
645}
646
647impl Debug for WlOutputSubpixel {
648    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
649        let name = match *self {
650            Self::UNKNOWN => "UNKNOWN",
651            Self::NONE => "NONE",
652            Self::HORIZONTAL_RGB => "HORIZONTAL_RGB",
653            Self::HORIZONTAL_BGR => "HORIZONTAL_BGR",
654            Self::VERTICAL_RGB => "VERTICAL_RGB",
655            Self::VERTICAL_BGR => "VERTICAL_BGR",
656            _ => return Debug::fmt(&self.0, f),
657        };
658        f.write_str(name)
659    }
660}
661
662/// transformation applied to buffer contents
663///
664/// This describes transformations that clients and compositors apply to
665/// buffer contents.
666///
667/// The flipped values correspond to an initial flip around a
668/// vertical axis followed by rotation.
669///
670/// The purpose is mainly to allow clients to render accordingly and
671/// tell the compositor, so that for fullscreen surfaces, the
672/// compositor will still be able to scan out directly from client
673/// surfaces.
674#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
675#[allow(dead_code)]
676pub struct WlOutputTransform(pub u32);
677
678impl WlOutputTransform {
679    /// no transform
680    #[allow(dead_code)]
681    pub const NORMAL: Self = Self(0);
682
683    /// 90 degrees counter-clockwise
684    #[allow(dead_code)]
685    pub const _90: Self = Self(1);
686
687    /// 180 degrees counter-clockwise
688    #[allow(dead_code)]
689    pub const _180: Self = Self(2);
690
691    /// 270 degrees counter-clockwise
692    #[allow(dead_code)]
693    pub const _270: Self = Self(3);
694
695    /// 180 degree flip around a vertical axis
696    #[allow(dead_code)]
697    pub const FLIPPED: Self = Self(4);
698
699    /// flip and rotate 90 degrees counter-clockwise
700    #[allow(dead_code)]
701    pub const FLIPPED_90: Self = Self(5);
702
703    /// flip and rotate 180 degrees counter-clockwise
704    #[allow(dead_code)]
705    pub const FLIPPED_180: Self = Self(6);
706
707    /// flip and rotate 270 degrees counter-clockwise
708    #[allow(dead_code)]
709    pub const FLIPPED_270: Self = Self(7);
710}
711
712impl Debug for WlOutputTransform {
713    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
714        let name = match *self {
715            Self::NORMAL => "NORMAL",
716            Self::_90 => "_90",
717            Self::_180 => "_180",
718            Self::_270 => "_270",
719            Self::FLIPPED => "FLIPPED",
720            Self::FLIPPED_90 => "FLIPPED_90",
721            Self::FLIPPED_180 => "FLIPPED_180",
722            Self::FLIPPED_270 => "FLIPPED_270",
723            _ => return Debug::fmt(&self.0, f),
724        };
725        f.write_str(name)
726    }
727}
728
729/// mode information
730///
731/// These flags describe properties of an output mode.
732/// They are used in the flags bitfield of the mode event.
733#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
734#[allow(dead_code)]
735pub struct WlOutputMode(pub u32);
736
737/// An iterator over the set bits in a [WlOutputMode].
738///
739/// You can construct this with the `IntoIterator` implementation of `WlOutputMode`.
740#[derive(Clone, Debug)]
741pub struct WlOutputModeIter(pub u32);
742
743impl WlOutputMode {
744    /// indicates this is the current mode
745    #[allow(dead_code)]
746    pub const CURRENT: Self = Self(0x1);
747
748    /// indicates this is the preferred mode
749    #[allow(dead_code)]
750    pub const PREFERRED: Self = Self(0x2);
751}
752
753#[allow(dead_code)]
754impl WlOutputMode {
755    #[inline]
756    pub const fn empty() -> Self {
757        Self(0)
758    }
759
760    #[inline]
761    #[must_use]
762    pub const fn is_empty(self) -> bool {
763        self.0 == 0
764    }
765
766    #[inline]
767    #[must_use]
768    pub const fn contains(self, other: Self) -> bool {
769        self.0 & other.0 == other.0
770    }
771
772    #[inline]
773    #[must_use]
774    pub const fn intersects(self, other: Self) -> bool {
775        self.0 & other.0 != 0
776    }
777
778    #[inline]
779    pub const fn insert(&mut self, other: Self) {
780        *self = self.union(other);
781    }
782
783    #[inline]
784    pub const fn remove(&mut self, other: Self) {
785        *self = self.difference(other);
786    }
787
788    #[inline]
789    pub const fn toggle(&mut self, other: Self) {
790        *self = self.symmetric_difference(other);
791    }
792
793    #[inline]
794    pub const fn set(&mut self, other: Self, value: bool) {
795        if value {
796            self.insert(other);
797        } else {
798            self.remove(other);
799        }
800    }
801
802    #[inline]
803    #[must_use]
804    pub const fn intersection(self, other: Self) -> Self {
805        Self(self.0 & other.0)
806    }
807
808    #[inline]
809    #[must_use]
810    pub const fn union(self, other: Self) -> Self {
811        Self(self.0 | other.0)
812    }
813
814    #[inline]
815    #[must_use]
816    pub const fn difference(self, other: Self) -> Self {
817        Self(self.0 & !other.0)
818    }
819
820    #[inline]
821    #[must_use]
822    pub const fn complement(self) -> Self {
823        Self(!self.0)
824    }
825
826    #[inline]
827    #[must_use]
828    pub const fn symmetric_difference(self, other: Self) -> Self {
829        Self(self.0 ^ other.0)
830    }
831
832    #[inline]
833    pub const fn all_known() -> Self {
834        #[allow(clippy::eq_op, clippy::identity_op)]
835        Self(0 | 0x1 | 0x2)
836    }
837}
838
839impl Iterator for WlOutputModeIter {
840    type Item = WlOutputMode;
841
842    fn next(&mut self) -> Option<Self::Item> {
843        if self.0 == 0 {
844            return None;
845        }
846        let bit = 1 << self.0.trailing_zeros();
847        self.0 &= !bit;
848        Some(WlOutputMode(bit))
849    }
850}
851
852impl IntoIterator for WlOutputMode {
853    type Item = WlOutputMode;
854    type IntoIter = WlOutputModeIter;
855
856    fn into_iter(self) -> Self::IntoIter {
857        WlOutputModeIter(self.0)
858    }
859}
860
861impl BitAnd for WlOutputMode {
862    type Output = Self;
863
864    fn bitand(self, rhs: Self) -> Self::Output {
865        self.intersection(rhs)
866    }
867}
868
869impl BitAndAssign for WlOutputMode {
870    fn bitand_assign(&mut self, rhs: Self) {
871        *self = self.intersection(rhs);
872    }
873}
874
875impl BitOr for WlOutputMode {
876    type Output = Self;
877
878    fn bitor(self, rhs: Self) -> Self::Output {
879        self.union(rhs)
880    }
881}
882
883impl BitOrAssign for WlOutputMode {
884    fn bitor_assign(&mut self, rhs: Self) {
885        *self = self.union(rhs);
886    }
887}
888
889impl BitXor for WlOutputMode {
890    type Output = Self;
891
892    fn bitxor(self, rhs: Self) -> Self::Output {
893        self.symmetric_difference(rhs)
894    }
895}
896
897impl BitXorAssign for WlOutputMode {
898    fn bitxor_assign(&mut self, rhs: Self) {
899        *self = self.symmetric_difference(rhs);
900    }
901}
902
903impl Sub for WlOutputMode {
904    type Output = Self;
905
906    fn sub(self, rhs: Self) -> Self::Output {
907        self.difference(rhs)
908    }
909}
910
911impl SubAssign for WlOutputMode {
912    fn sub_assign(&mut self, rhs: Self) {
913        *self = self.difference(rhs);
914    }
915}
916
917impl Not for WlOutputMode {
918    type Output = Self;
919
920    fn not(self) -> Self::Output {
921        self.complement()
922    }
923}
924
925impl Debug for WlOutputMode {
926    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
927        let mut v = self.0;
928        let mut first = true;
929        if v & 0x1 == 0x1 {
930            v &= !0x1;
931            if first {
932                first = false;
933            } else {
934                f.write_str(" | ")?;
935            }
936            f.write_str("CURRENT")?;
937        }
938        if v & 0x2 == 0x2 {
939            v &= !0x2;
940            if first {
941                first = false;
942            } else {
943                f.write_str(" | ")?;
944            }
945            f.write_str("PREFERRED")?;
946        }
947        if v != 0 {
948            if first {
949                first = false;
950            } else {
951                f.write_str(" | ")?;
952            }
953            write!(f, "0x{v:032x}")?;
954        }
955        if first {
956            f.write_str("0")?;
957        }
958        Ok(())
959    }
960}
961
962/// Functional event handlers.
963pub mod event_handlers {
964    use super::*;
965
966    /// Event handler for geometry events.
967    pub struct Geometry<T, F>(F, PhantomData<fn(&mut T)>);
968    impl<T, F> WlOutputEventHandler for Geometry<T, F>
969    where
970        T: 'static,
971        F: Fn(
972            &mut T,
973            &WlOutputRef,
974            i32,
975            i32,
976            i32,
977            i32,
978            WlOutputSubpixel,
979            &str,
980            &str,
981            WlOutputTransform,
982        ),
983    {
984        type Data = T;
985
986        #[inline]
987        fn geometry(
988            &self,
989            _data: &mut T,
990            _slf: &WlOutputRef,
991            x: i32,
992            y: i32,
993            physical_width: i32,
994            physical_height: i32,
995            subpixel: WlOutputSubpixel,
996            make: &str,
997            model: &str,
998            transform: WlOutputTransform,
999        ) {
1000            self.0(
1001                _data,
1002                _slf,
1003                x,
1004                y,
1005                physical_width,
1006                physical_height,
1007                subpixel,
1008                make,
1009                model,
1010                transform,
1011            )
1012        }
1013    }
1014
1015    /// Event handler for mode events.
1016    pub struct Mode<T, F>(F, PhantomData<fn(&mut T)>);
1017    impl<T, F> WlOutputEventHandler for Mode<T, F>
1018    where
1019        T: 'static,
1020        F: Fn(&mut T, &WlOutputRef, WlOutputMode, i32, i32, i32),
1021    {
1022        type Data = T;
1023
1024        #[inline]
1025        fn mode(
1026            &self,
1027            _data: &mut T,
1028            _slf: &WlOutputRef,
1029            flags: WlOutputMode,
1030            width: i32,
1031            height: i32,
1032            refresh: i32,
1033        ) {
1034            self.0(_data, _slf, flags, width, height, refresh)
1035        }
1036    }
1037
1038    /// Event handler for done events.
1039    pub struct Done<T, F>(F, PhantomData<fn(&mut T)>);
1040    impl<T, F> WlOutputEventHandler for Done<T, F>
1041    where
1042        T: 'static,
1043        F: Fn(&mut T, &WlOutputRef),
1044    {
1045        type Data = T;
1046
1047        #[inline]
1048        fn done(&self, _data: &mut T, _slf: &WlOutputRef) {
1049            self.0(_data, _slf)
1050        }
1051    }
1052
1053    /// Event handler for scale events.
1054    pub struct Scale<T, F>(F, PhantomData<fn(&mut T)>);
1055    impl<T, F> WlOutputEventHandler for Scale<T, F>
1056    where
1057        T: 'static,
1058        F: Fn(&mut T, &WlOutputRef, i32),
1059    {
1060        type Data = T;
1061
1062        #[inline]
1063        fn scale(&self, _data: &mut T, _slf: &WlOutputRef, factor: i32) {
1064            self.0(_data, _slf, factor)
1065        }
1066    }
1067
1068    /// Event handler for name events.
1069    pub struct Name<T, F>(F, PhantomData<fn(&mut T)>);
1070    impl<T, F> WlOutputEventHandler for Name<T, F>
1071    where
1072        T: 'static,
1073        F: Fn(&mut T, &WlOutputRef, &str),
1074    {
1075        type Data = T;
1076
1077        #[inline]
1078        fn name(&self, _data: &mut T, _slf: &WlOutputRef, name: &str) {
1079            self.0(_data, _slf, name)
1080        }
1081    }
1082
1083    /// Event handler for description events.
1084    pub struct Description<T, F>(F, PhantomData<fn(&mut T)>);
1085    impl<T, F> WlOutputEventHandler for Description<T, F>
1086    where
1087        T: 'static,
1088        F: Fn(&mut T, &WlOutputRef, &str),
1089    {
1090        type Data = T;
1091
1092        #[inline]
1093        fn description(&self, _data: &mut T, _slf: &WlOutputRef, description: &str) {
1094            self.0(_data, _slf, description)
1095        }
1096    }
1097
1098    impl WlOutput {
1099        /// Creates an event handler for geometry events.
1100        ///
1101        /// The event handler ignores all other events.
1102        #[allow(dead_code)]
1103        pub fn on_geometry<T, F>(f: F) -> Geometry<T, F>
1104        where
1105            T: 'static,
1106            F: Fn(
1107                &mut T,
1108                &WlOutputRef,
1109                i32,
1110                i32,
1111                i32,
1112                i32,
1113                WlOutputSubpixel,
1114                &str,
1115                &str,
1116                WlOutputTransform,
1117            ),
1118        {
1119            Geometry(f, PhantomData)
1120        }
1121
1122        /// Creates an event handler for mode events.
1123        ///
1124        /// The event handler ignores all other events.
1125        #[allow(dead_code)]
1126        pub fn on_mode<T, F>(f: F) -> Mode<T, F>
1127        where
1128            T: 'static,
1129            F: Fn(&mut T, &WlOutputRef, WlOutputMode, i32, i32, i32),
1130        {
1131            Mode(f, PhantomData)
1132        }
1133
1134        /// Creates an event handler for done events.
1135        ///
1136        /// The event handler ignores all other events.
1137        #[allow(dead_code)]
1138        pub fn on_done<T, F>(f: F) -> Done<T, F>
1139        where
1140            T: 'static,
1141            F: Fn(&mut T, &WlOutputRef),
1142        {
1143            Done(f, PhantomData)
1144        }
1145
1146        /// Creates an event handler for scale events.
1147        ///
1148        /// The event handler ignores all other events.
1149        #[allow(dead_code)]
1150        pub fn on_scale<T, F>(f: F) -> Scale<T, F>
1151        where
1152            T: 'static,
1153            F: Fn(&mut T, &WlOutputRef, i32),
1154        {
1155            Scale(f, PhantomData)
1156        }
1157
1158        /// Creates an event handler for name events.
1159        ///
1160        /// The event handler ignores all other events.
1161        #[allow(dead_code)]
1162        pub fn on_name<T, F>(f: F) -> Name<T, F>
1163        where
1164            T: 'static,
1165            F: Fn(&mut T, &WlOutputRef, &str),
1166        {
1167            Name(f, PhantomData)
1168        }
1169
1170        /// Creates an event handler for description events.
1171        ///
1172        /// The event handler ignores all other events.
1173        #[allow(dead_code)]
1174        pub fn on_description<T, F>(f: F) -> Description<T, F>
1175        where
1176            T: 'static,
1177            F: Fn(&mut T, &WlOutputRef, &str),
1178        {
1179            Description(f, PhantomData)
1180        }
1181    }
1182}