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