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