use std::os::raw;
use std::ptr;
use crate::{
event_loop::{EventLoopBuilder, EventLoopWindowTarget},
monitor::MonitorHandle,
window::{Window, WindowBuilder},
};
use crate::dpi::Size;
use crate::platform_impl::{
x11::ffi::XVisualInfo, ApplicationName, Backend, Window as LinuxWindow, XLIB_ERROR_HOOKS,
};
pub use crate::platform_impl::{x11::util::WindowType as XWindowType, XNotSupported};
pub type XlibErrorHook =
Box<dyn Fn(*mut std::ffi::c_void, *mut std::ffi::c_void) -> bool + Send + Sync>;
#[inline]
pub fn register_xlib_error_hook(hook: XlibErrorHook) {
unsafe {
XLIB_ERROR_HOOKS.lock().unwrap().push(hook);
}
}
pub trait EventLoopWindowTargetExtX11 {
fn is_x11(&self) -> bool;
}
impl<T> EventLoopWindowTargetExtX11 for EventLoopWindowTarget<T> {
#[inline]
fn is_x11(&self) -> bool {
!self.p.is_wayland()
}
}
pub trait EventLoopBuilderExtX11 {
fn with_x11(&mut self) -> &mut Self;
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self;
}
impl<T> EventLoopBuilderExtX11 for EventLoopBuilder<T> {
#[inline]
fn with_x11(&mut self) -> &mut Self {
self.platform_specific.forced_backend = Some(Backend::X);
self
}
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
}
pub trait WindowExtX11 {
fn xlib_window(&self) -> Option<raw::c_ulong>;
fn xlib_display(&self) -> Option<*mut raw::c_void>;
fn xlib_screen_id(&self) -> Option<raw::c_int>;
fn xcb_connection(&self) -> Option<*mut raw::c_void>;
}
impl WindowExtX11 for Window {
#[inline]
fn xlib_window(&self) -> Option<raw::c_ulong> {
match self.window {
LinuxWindow::X(ref w) => Some(w.xlib_window()),
#[cfg(wayland_platform)]
_ => None,
}
}
#[inline]
fn xlib_display(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::X(ref w) => Some(w.xlib_display()),
#[cfg(wayland_platform)]
_ => None,
}
}
#[inline]
fn xlib_screen_id(&self) -> Option<raw::c_int> {
match self.window {
LinuxWindow::X(ref w) => Some(w.xlib_screen_id()),
#[cfg(wayland_platform)]
_ => None,
}
}
#[inline]
fn xcb_connection(&self) -> Option<*mut raw::c_void> {
match self.window {
LinuxWindow::X(ref w) => Some(w.xcb_connection()),
#[cfg(wayland_platform)]
_ => None,
}
}
}
pub trait WindowBuilderExtX11 {
fn with_x11_visual<T>(self, visual_infos: *const T) -> Self;
fn with_x11_screen(self, screen_id: i32) -> Self;
fn with_name(self, general: impl Into<String>, instance: impl Into<String>) -> Self;
fn with_override_redirect(self, override_redirect: bool) -> Self;
fn with_x11_window_type(self, x11_window_type: Vec<XWindowType>) -> Self;
fn with_base_size<S: Into<Size>>(self, base_size: S) -> Self;
}
impl WindowBuilderExtX11 for WindowBuilder {
#[inline]
fn with_x11_visual<T>(mut self, visual_infos: *const T) -> Self {
{
self.platform_specific.visual_infos =
Some(unsafe { ptr::read(visual_infos as *const XVisualInfo) });
}
self
}
#[inline]
fn with_x11_screen(mut self, screen_id: i32) -> Self {
self.platform_specific.screen_id = Some(screen_id);
self
}
#[inline]
fn with_name(mut self, general: impl Into<String>, instance: impl Into<String>) -> Self {
self.platform_specific.name = Some(ApplicationName::new(general.into(), instance.into()));
self
}
#[inline]
fn with_override_redirect(mut self, override_redirect: bool) -> Self {
self.platform_specific.override_redirect = override_redirect;
self
}
#[inline]
fn with_x11_window_type(mut self, x11_window_types: Vec<XWindowType>) -> Self {
self.platform_specific.x11_window_types = x11_window_types;
self
}
#[inline]
fn with_base_size<S: Into<Size>>(mut self, base_size: S) -> Self {
self.platform_specific.base_size = Some(base_size.into());
self
}
}
pub trait MonitorHandleExtX11 {
fn native_id(&self) -> u32;
}
impl MonitorHandleExtX11 for MonitorHandle {
#[inline]
fn native_id(&self) -> u32 {
self.inner.native_identifier()
}
}