1// Take a look at the license at the top of the repository in the LICENSE file.
23#[cfg(feature = "xlib")]
4#[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
5use std::{boxed::Boxas Box_, mem::transmute};
67#[cfg(feature = "xlib")]
8#[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
9use glib::signal::{connect_raw, SignalHandlerId};
10use glib::translate::*;
11#[cfg(all(feature = "v4_4", feature = "egl"))]
12#[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
13use khronos_eglas egl;
14#[cfg(feature = "xlib")]
15#[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
16use x11::xlib;
17#[cfg(feature = "xlib")]
18#[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
19use x11::xlib::{Cursoras XCursor, Windowas XWindow};
2021use crate::{ffi, prelude::*, X11Display};
22#[cfg(not(feature = "xlib"))]
23use crate::{XCursor, XWindow};
2425impl X11Display {
26/// Retrieves the EGL display connection object for the given GDK display.
27 ///
28 /// This function returns `NULL` if GDK is using GLX.
29 ///
30 /// # Deprecated since 4.18
31 ///
32 ///
33 /// # Returns
34 ///
35 /// the EGL display object
36#[cfg(all(feature = "v4_4", feature = "egl"))]
37 #[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
38 #[doc(alias = "gdk_x11_display_get_egl_display")]
39 #[doc(alias = "get_egl_display")]
40pub fn egl_display(&self) -> Option<egl::Display> {
41unsafe {
42let ptr = ffi::gdk_x11_display_get_egl_display(self.to_glib_none().0);
43if ptr.is_null() {
44None45 } else {
46Some(egl::Display::from_ptr(ptr))
47 }
48 }
49 }
5051/// Returns the X cursor belonging to a [`gdk::Cursor`][crate::gdk::Cursor], potentially
52 /// creating the cursor.
53 ///
54 /// Be aware that the returned cursor may not be unique to @cursor.
55 /// It may for example be shared with its fallback cursor. On old
56 /// X servers that don't support the XCursor extension, all cursors
57 /// may even fall back to a few default cursors.
58 ///
59 /// # Deprecated since 4.18
60 ///
61 /// ## `cursor`
62 /// a [`gdk::Cursor`][crate::gdk::Cursor]
63 ///
64 /// # Returns
65 ///
66 /// an Xlib Cursor.
67#[doc(alias = "gdk_x11_display_get_xcursor")]
68 #[doc(alias = "get_xcursor")]
69pub fn xcursor(&self, cursor: &gdk::Cursor) -> XCursor {
70unsafe { ffi::gdk_x11_display_get_xcursor(self.to_glib_none().0, cursor.to_glib_none().0) }
71 }
7273/// Returns the root X window used by [`gdk::Display`][crate::gdk::Display].
74 ///
75 /// # Returns
76 ///
77 /// an X Window
78#[doc(alias = "gdk_x11_display_get_xrootwindow")]
79 #[doc(alias = "get_xrootwindow")]
80pub fn xrootwindow(&self) -> XWindow {
81unsafe { ffi::gdk_x11_display_get_xrootwindow(self.to_glib_none().0) }
82 }
8384/// Returns the X display of a [`gdk::Display`][crate::gdk::Display].
85 ///
86 /// # Returns
87 ///
88 /// an X display
89#[cfg(feature = "xlib")]
90 #[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
91 #[doc(alias = "gdk_x11_display_get_xdisplay")]
92 #[doc(alias = "get_xdisplay")]
93 #[allow(clippy::missing_safety_doc)]
94pub unsafe fn xdisplay(&self) -> *mut xlib::Display {
95ffi::gdk_x11_display_get_xdisplay(self.to_glib_none().0) as *mut xlib::Display96 }
9798/// Returns the X Screen used by [`gdk::Display`][crate::gdk::Display].
99 ///
100 /// # Returns
101 ///
102 /// an X Screen
103#[cfg(feature = "xlib")]
104 #[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
105 #[doc(alias = "gdk_x11_display_get_xscreen")]
106 #[doc(alias = "get_xscreen")]
107 #[allow(clippy::missing_safety_doc)]
108pub unsafe fn xscreen(&self) -> *mut xlib::Screen {
109ffi::gdk_x11_display_get_xscreen(self.to_glib_none().0) as *mut xlib::Screen110 }
111112/// The ::xevent signal is a low level signal that is emitted
113 /// whenever an XEvent has been received.
114 ///
115 /// When handlers to this signal return [`true`], no other handlers will be
116 /// invoked. In particular, the default handler for this function is
117 /// GDK's own event handling mechanism, so by returning [`true`] for an event
118 /// that GDK expects to translate, you may break GDK and/or GTK+ in
119 /// interesting ways. You have been warned.
120 ///
121 /// If you want this signal handler to queue a [`gdk::Event`][crate::gdk::Event], you can use
122 /// gdk_display_put_event().
123 ///
124 /// If you are interested in X GenericEvents, bear in mind that
125 /// XGetEventData() has been already called on the event, and
126 /// XFreeEventData() will be called afterwards.
127 /// ## `xevent`
128 /// a pointer to the XEvent to process
129 ///
130 /// # Returns
131 ///
132 /// [`true`] to stop other handlers from being invoked for the event.
133 /// [`false`] to propagate the event further.
134#[cfg(feature = "xlib")]
135 #[cfg_attr(docsrs, doc(cfg(feature = "xlib")))]
136 #[doc(alias = "xevent")]
137 #[allow(clippy::missing_safety_doc)]
138pub unsafe fn connect_xevent<F: Fn(&Self, *mut xlib::XEvent) -> glib::Propagation + 'static>(
139&self,
140 f: F,
141 ) -> SignalHandlerId {
142unsafe extern "C" fn xevent_trampoline<
143 F: Fn(&X11Display, *mut xlib::XEvent) -> glib::Propagation + 'static,
144 >(
145 this: *mut ffi::GdkX11Display,
146 xevent: glib::ffi::gpointer,
147 f: glib::ffi::gpointer,
148 ) -> glib::ffi::gboolean {
149let f: &F = &*(fas *const F);
150f(&from_glib_borrow(this), xeventas *mut xlib::XEvent).into_glib()
151 }
152let f: Box_<F> = Box_::new(f);
153connect_raw(
154self.as_ptr() as *mut _,
155b"xevent\0".as_ptr() as *const _,
156Some(transmute::<*const (), unsafe extern "C" fn()>(
157xevent_trampoline::<F> as *const (),
158 )),
159Box_::into_raw(f),
160 )
161 }
162163/// Sets the program class.
164 ///
165 /// The X11 backend uses the program class to set the class name part
166 /// of the `WM_CLASS` property on toplevel windows; see the ICCCM.
167 /// ## `display`
168 /// a [`gdk::Display`][crate::gdk::Display]
169 /// ## `program_class`
170 /// a string
171#[doc(alias = "gdk_x11_display_set_program_class")]
172pub fn set_program_class(&self, program_class: impl IntoGStr) {
173assert_initialized_main_thread!();
174unsafe {
175program_class.run_with_gstr(|program_class| {
176ffi::gdk_x11_display_set_program_class(
177self.upcast_ref::<gdk::Display>().to_glib_none().0,
178program_class.as_ptr(),
179 );
180 });
181 }
182 }
183}