gdk4/
cursor.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{ffi, Cursor, Texture};
4use glib::translate::*;
5use std::boxed::Box as Box_;
6
7impl Cursor {
8    /// Creates a new callback-based cursor object.
9    ///
10    /// Cursors of this kind produce textures for the cursor
11    /// image on demand, when the @callback is called.
12    /// ## `callback`
13    /// the `GdkCursorGetTextureCallback`
14    /// ## `fallback`
15    /// the [`Cursor`][crate::Cursor] to fall back to when
16    ///   this one cannot be supported
17    ///
18    /// # Returns
19    ///
20    /// a new [`Cursor`][crate::Cursor]
21    #[cfg(feature = "v4_16")]
22    #[cfg_attr(docsrs, doc(cfg(feature = "v4_16")))]
23    #[doc(alias = "gdk_cursor_new_from_callback")]
24    #[doc(alias = "new_from_callback")]
25    pub fn from_callback<
26        P: Fn(&Cursor, i32, f64, &mut i32, &mut i32, &mut i32, &mut i32) -> Texture + 'static,
27    >(
28        callback: P,
29        fallback: Option<&Cursor>,
30    ) -> Option<Cursor> {
31        assert_initialized_main_thread!();
32        let callback_data: Box_<P> = Box_::new(callback);
33        unsafe extern "C" fn callback_func<
34            P: Fn(&Cursor, i32, f64, &mut i32, &mut i32, &mut i32, &mut i32) -> Texture + 'static,
35        >(
36            cursor: *mut ffi::GdkCursor,
37            cursor_size: libc::c_int,
38            scale: libc::c_double,
39            width: *mut libc::c_int,
40            height: *mut libc::c_int,
41            hotspot_x: *mut libc::c_int,
42            hotspot_y: *mut libc::c_int,
43            data: glib::ffi::gpointer,
44        ) -> *mut ffi::GdkTexture {
45            let cursor = from_glib_borrow(cursor);
46            let callback = &*(data as *mut P);
47            (*callback)(
48                &cursor,
49                cursor_size,
50                scale,
51                &mut *width,
52                &mut *height,
53                &mut *hotspot_x,
54                &mut *hotspot_y,
55            )
56            /*Not checked*/
57            .to_glib_none()
58            .0
59        }
60        let callback = Some(callback_func::<P> as _);
61        unsafe extern "C" fn destroy_func<
62            P: Fn(&Cursor, i32, f64, &mut i32, &mut i32, &mut i32, &mut i32) -> Texture + 'static,
63        >(
64            data: glib::ffi::gpointer,
65        ) {
66            let _callback = Box_::from_raw(data as *mut P);
67        }
68        let destroy_call2 = Some(destroy_func::<P> as _);
69        let super_callback0: Box_<P> = callback_data;
70        unsafe {
71            from_glib_full(ffi::gdk_cursor_new_from_callback(
72                callback,
73                Box_::into_raw(super_callback0) as *mut _,
74                destroy_call2,
75                fallback.to_glib_none().0,
76            ))
77        }
78    }
79}