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}