gdk4_wayland/
wayland_display.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3#[cfg(any(feature = "wayland_crate", all(feature = "v4_4", feature = "egl")))]
4#[cfg_attr(
5    docsrs,
6    doc(cfg(any(feature = "wayland_crate", all(feature = "v4_4", feature = "egl"))))
7)]
8use crate::ffi;
9#[cfg(any(feature = "wayland_crate", all(feature = "v4_4", feature = "egl")))]
10#[cfg_attr(docsrs, doc(cfg(feature = "wayland_crate")))]
11use glib::translate::*;
12#[cfg(feature = "wayland_crate")]
13#[cfg_attr(docsrs, doc(cfg(feature = "wayland_crate")))]
14use glib::{prelude::*, Quark};
15
16#[cfg(all(feature = "v4_4", feature = "egl"))]
17#[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
18use khronos_egl as egl;
19#[cfg(feature = "wayland_crate")]
20#[cfg_attr(docsrs, doc(cfg(feature = "wayland_crate")))]
21use wayland_client::{
22    backend::ObjectId,
23    protocol::{wl_compositor::WlCompositor, wl_display::WlDisplay},
24    Proxy,
25};
26
27use crate::WaylandDisplay;
28
29impl WaylandDisplay {
30    /// Retrieves the EGL display connection object for the given GDK display.
31    ///
32    /// # Returns
33    ///
34    /// the EGL display
35    #[cfg(all(feature = "v4_4", feature = "egl"))]
36    #[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
37    #[doc(alias = "gdk_wayland_display_get_egl_display")]
38    #[doc(alias = "get_egl_display")]
39    pub fn egl_display(&self) -> Option<egl::Display> {
40        unsafe {
41            let ptr = ffi::gdk_wayland_display_get_egl_display(self.to_glib_none().0);
42            if ptr.is_null() {
43                None
44            } else {
45                Some(egl::Display::from_ptr(ptr))
46            }
47        }
48    }
49
50    /// Returns the Wayland `wl_compositor` of a display.
51    ///
52    /// # Returns
53    ///
54    /// a Wayland `wl_compositor`
55    #[doc(alias = "gdk_wayland_display_get_wl_compositor")]
56    #[doc(alias = "get_wl_compositor")]
57    #[cfg(feature = "wayland_crate")]
58    #[cfg_attr(docsrs, doc(cfg(feature = "wayland_crate")))]
59    pub fn wl_compositor(&self) -> Option<WlCompositor> {
60        unsafe {
61            let compositor_ptr = ffi::gdk_wayland_display_get_wl_compositor(self.to_glib_none().0);
62            if compositor_ptr.is_null() {
63                None
64            } else {
65                let cnx = self.connection();
66                let id = ObjectId::from_ptr(WlCompositor::interface(), compositor_ptr as *mut _)
67                    .unwrap();
68
69                WlCompositor::from_id(&cnx, id).ok()
70            }
71        }
72    }
73
74    /// Returns the Wayland `wl_display` of a display.
75    ///
76    /// # Returns
77    ///
78    /// a Wayland `wl_display`
79    #[doc(alias = "gdk_wayland_display_get_wl_display")]
80    #[doc(alias = "get_wl_display")]
81    #[cfg(feature = "wayland_crate")]
82    #[cfg_attr(docsrs, doc(cfg(feature = "wayland_crate")))]
83    pub fn wl_display(&self) -> Option<WlDisplay> {
84        unsafe {
85            let display_ptr = ffi::gdk_wayland_display_get_wl_display(self.to_glib_none().0);
86            if display_ptr.is_null() {
87                None
88            } else {
89                let cnx = self.connection();
90                let id = ObjectId::from_ptr(WlDisplay::interface(), display_ptr as *mut _).unwrap();
91
92                WlDisplay::from_id(&cnx, id).ok()
93            }
94        }
95    }
96
97    #[cfg(feature = "wayland_crate")]
98    pub(crate) fn connection(&self) -> wayland_client::Connection {
99        use std::sync::OnceLock;
100        static QUARK: OnceLock<Quark> = OnceLock::new();
101        let quark =
102            *QUARK.get_or_init(|| Quark::from_str("gtk-rs-wayland-display-connection-quark"));
103
104        unsafe {
105            match self.qdata::<Option<wayland_client::Connection>>(quark) {
106                Some(conn) => conn.as_ref().clone().unwrap(),
107                None => {
108                    let display_ptr =
109                        ffi::gdk_wayland_display_get_wl_display(self.to_glib_none().0);
110                    let backend = wayland_backend::sys::client::Backend::from_foreign_display(
111                        display_ptr as *mut _,
112                    );
113                    let conn = wayland_client::Connection::from_backend(backend);
114                    self.set_qdata(quark, conn.clone());
115
116                    conn
117                }
118            }
119        }
120    }
121}