Skip to content

Commit 6e0746c

Browse files
elmarcobilelmoussaoui
authored andcommitted
gdk-win32: implement Win32Display.add_filter()
Signed-off-by: Marc-André Lureau <[email protected]>
1 parent 592eed3 commit 6e0746c

File tree

4 files changed

+105
-12
lines changed

4 files changed

+105
-12
lines changed

gdk4-win32/Gir.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ status = "generate"
9595
[[object.function]]
9696
name = "get_egl_display"
9797
manual = true
98+
[[object.function]]
99+
pattern = "(add|remove)_filter"
100+
manual = true
98101

99102
[[object]]
100103
name = "GdkWin32.Win32HCursor"

gdk4-win32/src/auto/win32_display.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ glib::wrapper! {
1818
}
1919

2020
impl Win32Display {
21-
//#[doc(alias = "gdk_win32_display_add_filter")]
22-
//pub fn add_filter(&self, function: /*Unimplemented*/Fn(&Win32Display, /*Ignored*/win32::MSG, i32) -> Win32MessageFilterReturn, data: /*Unimplemented*/Option<Basic: Pointer>) {
23-
// unsafe { TODO: call ffi:gdk_win32_display_add_filter() }
24-
//}
25-
2621
#[doc(alias = "gdk_win32_display_get_win32hcursor")]
2722
#[doc(alias = "get_win32hcursor")]
2823
pub fn win32hcursor(&self, cursor: &gdk::Cursor) -> Win32HCursor {
@@ -34,11 +29,6 @@ impl Win32Display {
3429
}
3530
}
3631

37-
//#[doc(alias = "gdk_win32_display_remove_filter")]
38-
//pub fn remove_filter(&self, function: /*Unimplemented*/Fn(&Win32Display, /*Ignored*/win32::MSG, i32) -> Win32MessageFilterReturn, data: /*Unimplemented*/Option<Basic: Pointer>) {
39-
// unsafe { TODO: call ffi:gdk_win32_display_remove_filter() }
40-
//}
41-
4232
#[doc(alias = "gdk_win32_display_set_cursor_theme")]
4333
pub fn set_cursor_theme(&self, name: Option<&str>, size: i32) {
4434
unsafe {

gdk4-win32/src/lib.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ mod auto;
2121
pub use auto::*;
2222

2323
mod win32_display;
24+
pub use win32_display::Win32DisplayFilterHandle;
25+
2426
mod win32_hcursor;
2527
mod win32_surface;
2628

@@ -33,7 +35,33 @@ pub struct HICON(pub isize);
3335
#[cfg(not(feature = "win32"))]
3436
pub struct HWND(pub isize);
3537

38+
#[cfg(not(feature = "win32"))]
39+
#[repr(transparent)]
40+
pub struct WPARAM(pub usize);
41+
#[cfg(not(feature = "win32"))]
42+
#[repr(transparent)]
43+
pub struct LPARAM(pub isize);
44+
45+
#[cfg(not(feature = "win32"))]
46+
#[repr(C)]
47+
pub struct POINT {
48+
pub x: i32,
49+
pub y: i32,
50+
}
51+
52+
#[allow(non_snake_case)]
53+
#[cfg(not(feature = "win32"))]
54+
#[repr(C)]
55+
pub struct MSG {
56+
pub hwnd: HWND,
57+
pub message: u32,
58+
pub wParam: WPARAM,
59+
pub lParam: LPARAM,
60+
pub time: u32,
61+
pub pt: POINT,
62+
}
63+
3664
#[cfg(feature = "win32")]
3765
pub use windows::Win32::Foundation::{HANDLE, HWND};
3866
#[cfg(feature = "win32")]
39-
pub use windows::Win32::UI::WindowsAndMessaging::{HCURSOR, HICON};
67+
pub use windows::Win32::UI::WindowsAndMessaging::{HCURSOR, HICON, MSG};

gdk4-win32/src/win32_display.rs

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Take a look at the license at the top of the repository in the LICENSE file.
22

3-
use crate::Win32Display;
3+
use crate::{ffi, glib, Win32Display, Win32MessageFilterReturn, MSG};
4+
use glib::translate::*;
45

56
#[cfg(any(all(feature = "v4_4", feature = "egl"), feature = "dox"))]
67
#[cfg_attr(feature = "dox", doc(cfg(all(feature = "v4_4", feature = "egl"))))]
@@ -24,4 +25,75 @@ impl Win32Display {
2425
}
2526
}
2627
}
28+
29+
#[doc(alias = "gdk_win32_display_add_filter")]
30+
pub fn add_filter<F>(&self, filter_func: F) -> Win32DisplayFilterHandle
31+
where
32+
F: Fn(&Self, &mut MSG, &mut i32) -> Win32MessageFilterReturn + 'static,
33+
{
34+
unsafe extern "C" fn trampoline<
35+
F: Fn(&Win32Display, &mut MSG, &mut i32) -> Win32MessageFilterReturn + 'static,
36+
>(
37+
display: *mut ffi::GdkWin32Display,
38+
msg: glib::ffi::gpointer,
39+
return_value: *mut libc::c_int,
40+
box_: glib::ffi::gpointer,
41+
) -> i32 {
42+
let f: &F = &*(box_ as *const F);
43+
f(
44+
&from_glib_borrow(display as *mut ffi::GdkWin32Display),
45+
&mut *(msg as *mut MSG),
46+
&mut *return_value,
47+
)
48+
.into_glib()
49+
}
50+
51+
let box_ = Box::into_raw(Box::new(filter_func)) as *mut _;
52+
let func = unsafe {
53+
let func: ffi::GdkWin32MessageFilterFunc = Some(trampoline::<F>);
54+
ffi::gdk_win32_display_add_filter(self.to_glib_none().0, func, box_);
55+
func
56+
};
57+
58+
let display = glib::WeakRef::new();
59+
display.set(Some(self));
60+
61+
let drop_ = |b| unsafe {
62+
let _ = Box::<F>::from_raw(b as *mut _);
63+
};
64+
Win32DisplayFilterHandle {
65+
display,
66+
func,
67+
box_,
68+
drop_,
69+
}
70+
}
71+
}
72+
73+
// rustdoc-stripper-ignore-next
74+
/// An owned `Win32Display` filter.
75+
///
76+
/// A `Win32DisplayFilterHandle` removes itself from the `Win32Display` it is
77+
/// attached to when it is dropped.
78+
#[derive(Debug)]
79+
pub struct Win32DisplayFilterHandle {
80+
display: glib::WeakRef<Win32Display>,
81+
func: ffi::GdkWin32MessageFilterFunc,
82+
box_: glib::ffi::gpointer,
83+
drop_: fn(*mut libc::c_void),
84+
}
85+
86+
impl Drop for Win32DisplayFilterHandle {
87+
fn drop(&mut self) {
88+
unsafe {
89+
if let Some(display) = self.display.upgrade() {
90+
ffi::gdk_win32_display_remove_filter(
91+
display.to_glib_none().0,
92+
self.func,
93+
self.box_,
94+
);
95+
}
96+
(self.drop_)(self.box_);
97+
}
98+
}
2799
}

0 commit comments

Comments
 (0)