simple_window/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 data: *mut u8,
446 slf: &UntypedBorrowedProxy,
447 opcode: u32,
448 args: *mut wl_argument,
449 ) {
450 // SAFETY: This function requires that slf has the interface INTERFACE
451 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlOutputRef>(slf) };
452 match opcode {
453 0 => {
454 // SAFETY: INTERFACE requires that there are 8 arguments
455 let args = unsafe { &*args.cast::<[wl_argument; 8]>() };
456 // SAFETY: - INTERFACE requires that args[0] contains an int
457 let arg0 = unsafe { args[0].i };
458 // SAFETY: - INTERFACE requires that args[1] contains an int
459 let arg1 = unsafe { args[1].i };
460 // SAFETY: - INTERFACE requires that args[2] contains an int
461 let arg2 = unsafe { args[2].i };
462 // SAFETY: - INTERFACE requires that args[3] contains an int
463 let arg3 = unsafe { args[3].i };
464 // SAFETY: - INTERFACE requires that args[4] contains an int
465 let arg4 = unsafe { WlOutputSubpixel(args[4].u) };
466 // SAFETY: - INTERFACE requires that args[5] contains a string
467 // - if the pointer is not null, then it is a c string
468 let arg5 = unsafe { convert_string_arg("wl_output", "make", args[5].s) };
469 // SAFETY: - INTERFACE requires that args[6] contains a string
470 // - if the pointer is not null, then it is a c string
471 let arg6 = unsafe { convert_string_arg("wl_output", "model", args[6].s) };
472 // SAFETY: - INTERFACE requires that args[7] contains an int
473 let arg7 = unsafe { WlOutputTransform(args[7].u) };
474 self.0
475 .geometry(slf, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
476 }
477 1 => {
478 // SAFETY: INTERFACE requires that there are 4 arguments
479 let args = unsafe { &*args.cast::<[wl_argument; 4]>() };
480 // SAFETY: - INTERFACE requires that args[0] contains a uint
481 let arg0 = unsafe { WlOutputMode(args[0].u) };
482 // SAFETY: - INTERFACE requires that args[1] contains an int
483 let arg1 = unsafe { args[1].i };
484 // SAFETY: - INTERFACE requires that args[2] contains an int
485 let arg2 = unsafe { args[2].i };
486 // SAFETY: - INTERFACE requires that args[3] contains an int
487 let arg3 = unsafe { args[3].i };
488 self.0.mode(slf, arg0, arg1, arg2, arg3);
489 }
490 2 => {
491 self.0.done(slf);
492 }
493 3 => {
494 // SAFETY: INTERFACE requires that there are 1 arguments
495 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
496 // SAFETY: - INTERFACE requires that args[0] contains an int
497 let arg0 = unsafe { args[0].i };
498 self.0.scale(slf, arg0);
499 }
500 4 => {
501 // SAFETY: INTERFACE requires that there are 1 arguments
502 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
503 // SAFETY: - INTERFACE requires that args[0] contains a string
504 // - if the pointer is not null, then it is a c string
505 let arg0 = unsafe { convert_string_arg("wl_output", "name", args[0].s) };
506 self.0.name(slf, arg0);
507 }
508 5 => {
509 // SAFETY: INTERFACE requires that there are 1 arguments
510 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
511 // SAFETY: - INTERFACE requires that args[0] contains a string
512 // - if the pointer is not null, then it is a c string
513 let arg0 = unsafe { convert_string_arg("wl_output", "description", args[0].s) };
514 self.0.description(slf, arg0);
515 }
516 _ => {
517 invalid_opcode("wl_output", opcode);
518 }
519 }
520 }
521}
522
523impl<H> CreateEventHandler<H> for private::ProxyApi
524where
525 H: WlOutputEventHandler,
526{
527 type EventHandler = private::EventHandler<H>;
528
529 #[inline]
530 fn create_event_handler(handler: H) -> Self::EventHandler {
531 private::EventHandler(handler)
532 }
533}
534
535impl WlOutput {
536 /// Since when the subpixel.unknown enum variant is available.
537 #[allow(dead_code)]
538 pub const ENM__SUBPIXEL_UNKNOWN__SINCE: u32 = 1;
539 /// Since when the subpixel.none enum variant is available.
540 #[allow(dead_code)]
541 pub const ENM__SUBPIXEL_NONE__SINCE: u32 = 1;
542 /// Since when the subpixel.horizontal_rgb enum variant is available.
543 #[allow(dead_code)]
544 pub const ENM__SUBPIXEL_HORIZONTAL_RGB__SINCE: u32 = 1;
545 /// Since when the subpixel.horizontal_bgr enum variant is available.
546 #[allow(dead_code)]
547 pub const ENM__SUBPIXEL_HORIZONTAL_BGR__SINCE: u32 = 1;
548 /// Since when the subpixel.vertical_rgb enum variant is available.
549 #[allow(dead_code)]
550 pub const ENM__SUBPIXEL_VERTICAL_RGB__SINCE: u32 = 1;
551 /// Since when the subpixel.vertical_bgr enum variant is available.
552 #[allow(dead_code)]
553 pub const ENM__SUBPIXEL_VERTICAL_BGR__SINCE: u32 = 1;
554
555 /// Since when the transform.normal enum variant is available.
556 #[allow(dead_code)]
557 pub const ENM__TRANSFORM_NORMAL__SINCE: u32 = 1;
558 /// Since when the transform.90 enum variant is available.
559 #[allow(dead_code)]
560 pub const ENM__TRANSFORM_90__SINCE: u32 = 1;
561 /// Since when the transform.180 enum variant is available.
562 #[allow(dead_code)]
563 pub const ENM__TRANSFORM_180__SINCE: u32 = 1;
564 /// Since when the transform.270 enum variant is available.
565 #[allow(dead_code)]
566 pub const ENM__TRANSFORM_270__SINCE: u32 = 1;
567 /// Since when the transform.flipped enum variant is available.
568 #[allow(dead_code)]
569 pub const ENM__TRANSFORM_FLIPPED__SINCE: u32 = 1;
570 /// Since when the transform.flipped_90 enum variant is available.
571 #[allow(dead_code)]
572 pub const ENM__TRANSFORM_FLIPPED_90__SINCE: u32 = 1;
573 /// Since when the transform.flipped_180 enum variant is available.
574 #[allow(dead_code)]
575 pub const ENM__TRANSFORM_FLIPPED_180__SINCE: u32 = 1;
576 /// Since when the transform.flipped_270 enum variant is available.
577 #[allow(dead_code)]
578 pub const ENM__TRANSFORM_FLIPPED_270__SINCE: u32 = 1;
579
580 /// Since when the mode.current enum variant is available.
581 #[allow(dead_code)]
582 pub const ENM__MODE_CURRENT__SINCE: u32 = 1;
583 /// Since when the mode.preferred enum variant is available.
584 #[allow(dead_code)]
585 pub const ENM__MODE_PREFERRED__SINCE: u32 = 1;
586}
587
588/// subpixel geometry information
589///
590/// This enumeration describes how the physical
591/// pixels on an output are laid out.
592#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
593#[allow(dead_code)]
594pub struct WlOutputSubpixel(pub u32);
595
596impl WlOutputSubpixel {
597 /// unknown geometry
598 #[allow(dead_code)]
599 pub const UNKNOWN: Self = Self(0);
600
601 /// no geometry
602 #[allow(dead_code)]
603 pub const NONE: Self = Self(1);
604
605 /// horizontal RGB
606 #[allow(dead_code)]
607 pub const HORIZONTAL_RGB: Self = Self(2);
608
609 /// horizontal BGR
610 #[allow(dead_code)]
611 pub const HORIZONTAL_BGR: Self = Self(3);
612
613 /// vertical RGB
614 #[allow(dead_code)]
615 pub const VERTICAL_RGB: Self = Self(4);
616
617 /// vertical BGR
618 #[allow(dead_code)]
619 pub const VERTICAL_BGR: Self = Self(5);
620}
621
622impl Debug for WlOutputSubpixel {
623 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
624 let name = match *self {
625 Self::UNKNOWN => "UNKNOWN",
626 Self::NONE => "NONE",
627 Self::HORIZONTAL_RGB => "HORIZONTAL_RGB",
628 Self::HORIZONTAL_BGR => "HORIZONTAL_BGR",
629 Self::VERTICAL_RGB => "VERTICAL_RGB",
630 Self::VERTICAL_BGR => "VERTICAL_BGR",
631 _ => return Debug::fmt(&self.0, f),
632 };
633 f.write_str(name)
634 }
635}
636
637/// transformation applied to buffer contents
638///
639/// This describes transformations that clients and compositors apply to
640/// buffer contents.
641///
642/// The flipped values correspond to an initial flip around a
643/// vertical axis followed by rotation.
644///
645/// The purpose is mainly to allow clients to render accordingly and
646/// tell the compositor, so that for fullscreen surfaces, the
647/// compositor will still be able to scan out directly from client
648/// surfaces.
649#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
650#[allow(dead_code)]
651pub struct WlOutputTransform(pub u32);
652
653impl WlOutputTransform {
654 /// no transform
655 #[allow(dead_code)]
656 pub const NORMAL: Self = Self(0);
657
658 /// 90 degrees counter-clockwise
659 #[allow(dead_code)]
660 pub const _90: Self = Self(1);
661
662 /// 180 degrees counter-clockwise
663 #[allow(dead_code)]
664 pub const _180: Self = Self(2);
665
666 /// 270 degrees counter-clockwise
667 #[allow(dead_code)]
668 pub const _270: Self = Self(3);
669
670 /// 180 degree flip around a vertical axis
671 #[allow(dead_code)]
672 pub const FLIPPED: Self = Self(4);
673
674 /// flip and rotate 90 degrees counter-clockwise
675 #[allow(dead_code)]
676 pub const FLIPPED_90: Self = Self(5);
677
678 /// flip and rotate 180 degrees counter-clockwise
679 #[allow(dead_code)]
680 pub const FLIPPED_180: Self = Self(6);
681
682 /// flip and rotate 270 degrees counter-clockwise
683 #[allow(dead_code)]
684 pub const FLIPPED_270: Self = Self(7);
685}
686
687impl Debug for WlOutputTransform {
688 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
689 let name = match *self {
690 Self::NORMAL => "NORMAL",
691 Self::_90 => "_90",
692 Self::_180 => "_180",
693 Self::_270 => "_270",
694 Self::FLIPPED => "FLIPPED",
695 Self::FLIPPED_90 => "FLIPPED_90",
696 Self::FLIPPED_180 => "FLIPPED_180",
697 Self::FLIPPED_270 => "FLIPPED_270",
698 _ => return Debug::fmt(&self.0, f),
699 };
700 f.write_str(name)
701 }
702}
703
704/// mode information
705///
706/// These flags describe properties of an output mode.
707/// They are used in the flags bitfield of the mode event.
708#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
709#[allow(dead_code)]
710pub struct WlOutputMode(pub u32);
711
712/// An iterator over the set bits in a [WlOutputMode].
713///
714/// You can construct this with the `IntoIterator` implementation of `WlOutputMode`.
715#[derive(Clone, Debug)]
716pub struct WlOutputModeIter(pub u32);
717
718impl WlOutputMode {
719 /// indicates this is the current mode
720 #[allow(dead_code)]
721 pub const CURRENT: Self = Self(0x1);
722
723 /// indicates this is the preferred mode
724 #[allow(dead_code)]
725 pub const PREFERRED: Self = Self(0x2);
726}
727
728#[allow(dead_code)]
729impl WlOutputMode {
730 #[inline]
731 pub const fn empty() -> Self {
732 Self(0)
733 }
734
735 #[inline]
736 #[must_use]
737 pub const fn is_empty(self) -> bool {
738 self.0 == 0
739 }
740
741 #[inline]
742 #[must_use]
743 pub const fn contains(self, other: Self) -> bool {
744 self.0 & other.0 == other.0
745 }
746
747 #[inline]
748 #[must_use]
749 pub const fn intersects(self, other: Self) -> bool {
750 self.0 & other.0 != 0
751 }
752
753 #[inline]
754 pub const fn insert(&mut self, other: Self) {
755 *self = self.union(other);
756 }
757
758 #[inline]
759 pub const fn remove(&mut self, other: Self) {
760 *self = self.difference(other);
761 }
762
763 #[inline]
764 pub const fn toggle(&mut self, other: Self) {
765 *self = self.symmetric_difference(other);
766 }
767
768 #[inline]
769 pub const fn set(&mut self, other: Self, value: bool) {
770 if value {
771 self.insert(other);
772 } else {
773 self.remove(other);
774 }
775 }
776
777 #[inline]
778 #[must_use]
779 pub const fn intersection(self, other: Self) -> Self {
780 Self(self.0 & other.0)
781 }
782
783 #[inline]
784 #[must_use]
785 pub const fn union(self, other: Self) -> Self {
786 Self(self.0 | other.0)
787 }
788
789 #[inline]
790 #[must_use]
791 pub const fn difference(self, other: Self) -> Self {
792 Self(self.0 & !other.0)
793 }
794
795 #[inline]
796 #[must_use]
797 pub const fn complement(self) -> Self {
798 Self(!self.0)
799 }
800
801 #[inline]
802 #[must_use]
803 pub const fn symmetric_difference(self, other: Self) -> Self {
804 Self(self.0 ^ other.0)
805 }
806
807 #[inline]
808 pub const fn all_known() -> Self {
809 #[allow(clippy::eq_op, clippy::identity_op)]
810 Self(0 | 0x1 | 0x2)
811 }
812}
813
814impl Iterator for WlOutputModeIter {
815 type Item = WlOutputMode;
816
817 fn next(&mut self) -> Option<Self::Item> {
818 if self.0 == 0 {
819 return None;
820 }
821 let bit = 1 << self.0.trailing_zeros();
822 self.0 &= !bit;
823 Some(WlOutputMode(bit))
824 }
825}
826
827impl IntoIterator for WlOutputMode {
828 type Item = WlOutputMode;
829 type IntoIter = WlOutputModeIter;
830
831 fn into_iter(self) -> Self::IntoIter {
832 WlOutputModeIter(self.0)
833 }
834}
835
836impl BitAnd for WlOutputMode {
837 type Output = Self;
838
839 fn bitand(self, rhs: Self) -> Self::Output {
840 self.intersection(rhs)
841 }
842}
843
844impl BitAndAssign for WlOutputMode {
845 fn bitand_assign(&mut self, rhs: Self) {
846 *self = self.intersection(rhs);
847 }
848}
849
850impl BitOr for WlOutputMode {
851 type Output = Self;
852
853 fn bitor(self, rhs: Self) -> Self::Output {
854 self.union(rhs)
855 }
856}
857
858impl BitOrAssign for WlOutputMode {
859 fn bitor_assign(&mut self, rhs: Self) {
860 *self = self.union(rhs);
861 }
862}
863
864impl BitXor for WlOutputMode {
865 type Output = Self;
866
867 fn bitxor(self, rhs: Self) -> Self::Output {
868 self.symmetric_difference(rhs)
869 }
870}
871
872impl BitXorAssign for WlOutputMode {
873 fn bitxor_assign(&mut self, rhs: Self) {
874 *self = self.symmetric_difference(rhs);
875 }
876}
877
878impl Sub for WlOutputMode {
879 type Output = Self;
880
881 fn sub(self, rhs: Self) -> Self::Output {
882 self.difference(rhs)
883 }
884}
885
886impl SubAssign for WlOutputMode {
887 fn sub_assign(&mut self, rhs: Self) {
888 *self = self.difference(rhs);
889 }
890}
891
892impl Not for WlOutputMode {
893 type Output = Self;
894
895 fn not(self) -> Self::Output {
896 self.complement()
897 }
898}
899
900impl Debug for WlOutputMode {
901 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
902 let mut v = self.0;
903 let mut first = true;
904 if v & 0x1 == 0x1 {
905 v &= !0x1;
906 if first {
907 first = false;
908 } else {
909 f.write_str(" | ")?;
910 }
911 f.write_str("CURRENT")?;
912 }
913 if v & 0x2 == 0x2 {
914 v &= !0x2;
915 if first {
916 first = false;
917 } else {
918 f.write_str(" | ")?;
919 }
920 f.write_str("PREFERRED")?;
921 }
922 if v != 0 {
923 if first {
924 first = false;
925 } else {
926 f.write_str(" | ")?;
927 }
928 write!(f, "0x{v:032x}")?;
929 }
930 if first {
931 f.write_str("0")?;
932 }
933 Ok(())
934 }
935}
936
937/// Functional event handlers.
938pub mod event_handlers {
939 use super::*;
940
941 /// Event handler for geometry events.
942 pub struct Geometry<F>(F);
943 impl<F> WlOutputEventHandler for Geometry<F>
944 where
945 F: Fn(&WlOutputRef, i32, i32, i32, i32, WlOutputSubpixel, &str, &str, WlOutputTransform),
946 {
947 #[inline]
948 fn geometry(
949 &self,
950 _slf: &WlOutputRef,
951 x: i32,
952 y: i32,
953 physical_width: i32,
954 physical_height: i32,
955 subpixel: WlOutputSubpixel,
956 make: &str,
957 model: &str,
958 transform: WlOutputTransform,
959 ) {
960 self.0(
961 _slf,
962 x,
963 y,
964 physical_width,
965 physical_height,
966 subpixel,
967 make,
968 model,
969 transform,
970 )
971 }
972 }
973
974 /// Event handler for mode events.
975 pub struct Mode<F>(F);
976 impl<F> WlOutputEventHandler for Mode<F>
977 where
978 F: Fn(&WlOutputRef, WlOutputMode, i32, i32, i32),
979 {
980 #[inline]
981 fn mode(
982 &self,
983 _slf: &WlOutputRef,
984 flags: WlOutputMode,
985 width: i32,
986 height: i32,
987 refresh: i32,
988 ) {
989 self.0(_slf, flags, width, height, refresh)
990 }
991 }
992
993 /// Event handler for done events.
994 pub struct Done<F>(F);
995 impl<F> WlOutputEventHandler for Done<F>
996 where
997 F: Fn(&WlOutputRef),
998 {
999 #[inline]
1000 fn done(&self, _slf: &WlOutputRef) {
1001 self.0(_slf)
1002 }
1003 }
1004
1005 /// Event handler for scale events.
1006 pub struct Scale<F>(F);
1007 impl<F> WlOutputEventHandler for Scale<F>
1008 where
1009 F: Fn(&WlOutputRef, i32),
1010 {
1011 #[inline]
1012 fn scale(&self, _slf: &WlOutputRef, factor: i32) {
1013 self.0(_slf, factor)
1014 }
1015 }
1016
1017 /// Event handler for name events.
1018 pub struct Name<F>(F);
1019 impl<F> WlOutputEventHandler for Name<F>
1020 where
1021 F: Fn(&WlOutputRef, &str),
1022 {
1023 #[inline]
1024 fn name(&self, _slf: &WlOutputRef, name: &str) {
1025 self.0(_slf, name)
1026 }
1027 }
1028
1029 /// Event handler for description events.
1030 pub struct Description<F>(F);
1031 impl<F> WlOutputEventHandler for Description<F>
1032 where
1033 F: Fn(&WlOutputRef, &str),
1034 {
1035 #[inline]
1036 fn description(&self, _slf: &WlOutputRef, description: &str) {
1037 self.0(_slf, description)
1038 }
1039 }
1040
1041 impl WlOutput {
1042 /// Creates an event handler for geometry events.
1043 ///
1044 /// The event handler ignores all other events.
1045 #[allow(dead_code)]
1046 pub fn on_geometry<F>(f: F) -> Geometry<F>
1047 where
1048 F: Fn(
1049 &WlOutputRef,
1050 i32,
1051 i32,
1052 i32,
1053 i32,
1054 WlOutputSubpixel,
1055 &str,
1056 &str,
1057 WlOutputTransform,
1058 ),
1059 {
1060 Geometry(f)
1061 }
1062
1063 /// Creates an event handler for mode events.
1064 ///
1065 /// The event handler ignores all other events.
1066 #[allow(dead_code)]
1067 pub fn on_mode<F>(f: F) -> Mode<F>
1068 where
1069 F: Fn(&WlOutputRef, WlOutputMode, i32, i32, i32),
1070 {
1071 Mode(f)
1072 }
1073
1074 /// Creates an event handler for done events.
1075 ///
1076 /// The event handler ignores all other events.
1077 #[allow(dead_code)]
1078 pub fn on_done<F>(f: F) -> Done<F>
1079 where
1080 F: Fn(&WlOutputRef),
1081 {
1082 Done(f)
1083 }
1084
1085 /// Creates an event handler for scale events.
1086 ///
1087 /// The event handler ignores all other events.
1088 #[allow(dead_code)]
1089 pub fn on_scale<F>(f: F) -> Scale<F>
1090 where
1091 F: Fn(&WlOutputRef, i32),
1092 {
1093 Scale(f)
1094 }
1095
1096 /// Creates an event handler for name events.
1097 ///
1098 /// The event handler ignores all other events.
1099 #[allow(dead_code)]
1100 pub fn on_name<F>(f: F) -> Name<F>
1101 where
1102 F: Fn(&WlOutputRef, &str),
1103 {
1104 Name(f)
1105 }
1106
1107 /// Creates an event handler for description events.
1108 ///
1109 /// The event handler ignores all other events.
1110 #[allow(dead_code)]
1111 pub fn on_description<F>(f: F) -> Description<F>
1112 where
1113 F: Fn(&WlOutputRef, &str),
1114 {
1115 Description(f)
1116 }
1117 }
1118}