gdk4_win32/
win32_display.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4#[cfg(all(feature = "v4_4", feature = "egl"))]
5#[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
6use khronos_egl as egl;
7
8use crate::{ffi, Win32Display, Win32MessageFilterReturn, MSG};
9
10impl Win32Display {
11    /// Retrieves the EGL display connection object for the given GDK display.
12    ///
13    /// # Returns
14    ///
15    /// the EGL display
16    #[cfg(all(feature = "v4_4", feature = "egl"))]
17    #[cfg_attr(docsrs, doc(cfg(all(feature = "v4_4", feature = "egl"))))]
18    #[doc(alias = "gdk_win32_display_get_egl_display")]
19    #[doc(alias = "get_egl_display")]
20    pub fn egl_display(&self) -> Option<egl::Display> {
21        unsafe {
22            let ptr = ffi::gdk_win32_display_get_egl_display(self.to_glib_none().0);
23            if ptr.is_null() {
24                None
25            } else {
26                Some(egl::Display::from_ptr(ptr))
27            }
28        }
29    }
30
31    /// Adds an event filter to @window, allowing you to intercept messages
32    /// before they reach GDK. This is a low-level operation and makes it
33    /// easy to break GDK and/or GTK, so you have to know what you're
34    /// doing.
35    /// ## `function`
36    /// filter callback
37    #[doc(alias = "gdk_win32_display_add_filter")]
38    pub fn add_filter<F>(&self, filter_func: F) -> Win32DisplayFilterHandle
39    where
40        F: Fn(&Self, &mut MSG, &mut i32) -> Win32MessageFilterReturn + 'static,
41    {
42        unsafe extern "C" fn trampoline<
43            F: Fn(&Win32Display, &mut MSG, &mut i32) -> Win32MessageFilterReturn + 'static,
44        >(
45            display: *mut ffi::GdkWin32Display,
46            msg: glib::ffi::gpointer,
47            return_value: *mut libc::c_int,
48            box_: glib::ffi::gpointer,
49        ) -> i32 {
50            let f: &F = &*(box_ as *const F);
51            f(
52                &from_glib_borrow(display),
53                &mut *(msg as *mut MSG),
54                &mut *return_value,
55            )
56            .into_glib()
57        }
58
59        let box_ = Box::into_raw(Box::new(filter_func)) as *mut _;
60        let func = unsafe {
61            let func: ffi::GdkWin32MessageFilterFunc = Some(trampoline::<F>);
62            ffi::gdk_win32_display_add_filter(self.to_glib_none().0, func, box_);
63            func
64        };
65
66        let display = glib::WeakRef::new();
67        display.set(Some(self));
68
69        let drop_ = |b| unsafe {
70            let _ = Box::<F>::from_raw(b as *mut _);
71        };
72        Win32DisplayFilterHandle {
73            display,
74            func,
75            box_,
76            drop_,
77        }
78    }
79}
80
81// rustdoc-stripper-ignore-next
82/// An owned `Win32Display` filter.
83///
84/// A `Win32DisplayFilterHandle` removes itself from the `Win32Display` it is
85/// attached to when it is dropped.
86#[derive(Debug)]
87pub struct Win32DisplayFilterHandle {
88    display: glib::WeakRef<Win32Display>,
89    func: ffi::GdkWin32MessageFilterFunc,
90    box_: glib::ffi::gpointer,
91    drop_: fn(*mut libc::c_void),
92}
93
94impl Drop for Win32DisplayFilterHandle {
95    #[inline]
96    fn drop(&mut self) {
97        unsafe {
98            if let Some(display) = self.display.upgrade() {
99                ffi::gdk_win32_display_remove_filter(
100                    display.to_glib_none().0,
101                    self.func,
102                    self.box_,
103                );
104            }
105            (self.drop_)(self.box_);
106        }
107    }
108}