[go: up one dir, main page]

gtk4/
event_controller_key.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{boxed::Box as Box_, mem::transmute};
4
5use gdk::Key;
6use glib::{signal::connect_raw, translate::*, SignalHandlerId};
7
8use crate::{ffi, prelude::*, EventControllerKey};
9
10impl EventControllerKey {
11    pub fn connect_key_pressed<
12        F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) -> glib::Propagation + 'static,
13    >(
14        &self,
15        f: F,
16    ) -> SignalHandlerId {
17        unsafe extern "C" fn key_pressed_trampoline<
18            F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) -> glib::Propagation + 'static,
19        >(
20            this: *mut ffi::GtkEventControllerKey,
21            keyval: libc::c_uint,
22            keycode: libc::c_uint,
23            state: gdk::ffi::GdkModifierType,
24            f: glib::ffi::gpointer,
25        ) -> glib::ffi::gboolean {
26            let f: &F = &*(f as *const F);
27            f(
28                &from_glib_borrow(this),
29                from_glib(keyval),
30                keycode,
31                from_glib(state),
32            )
33            .into_glib()
34        }
35        unsafe {
36            let f: Box_<F> = Box_::new(f);
37            connect_raw(
38                self.as_ptr() as *mut _,
39                c"key-pressed".as_ptr() as *const _,
40                Some(transmute::<*const (), unsafe extern "C" fn()>(
41                    key_pressed_trampoline::<F> as *const (),
42                )),
43                Box_::into_raw(f),
44            )
45        }
46    }
47
48    pub fn connect_key_released<
49        F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) + 'static,
50    >(
51        &self,
52        f: F,
53    ) -> SignalHandlerId {
54        unsafe extern "C" fn key_released_trampoline<
55            F: Fn(&EventControllerKey, Key, u32, gdk::ModifierType) + 'static,
56        >(
57            this: *mut ffi::GtkEventControllerKey,
58            keyval: libc::c_uint,
59            keycode: libc::c_uint,
60            state: gdk::ffi::GdkModifierType,
61            f: glib::ffi::gpointer,
62        ) {
63            let f: &F = &*(f as *const F);
64            f(
65                &from_glib_borrow(this),
66                from_glib(keyval),
67                keycode,
68                from_glib(state),
69            )
70        }
71        unsafe {
72            let f: Box_<F> = Box_::new(f);
73            connect_raw(
74                self.as_ptr() as *mut _,
75                c"key-released".as_ptr() as *const _,
76                Some(transmute::<*const (), unsafe extern "C" fn()>(
77                    key_released_trampoline::<F> as *const (),
78                )),
79                Box_::into_raw(f),
80            )
81        }
82    }
83}