Skip to main content

gdk4/
cursor.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{Cursor, Texture, ffi};
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            unsafe {
46                let cursor = from_glib_borrow(cursor);
47                let callback = &*(data as *mut P);
48                (*callback)(
49                    &cursor,
50                    cursor_size,
51                    scale,
52                    &mut *width,
53                    &mut *height,
54                    &mut *hotspot_x,
55                    &mut *hotspot_y,
56                )
57                /*Not checked*/
58                .to_glib_none()
59                .0
60            }
61        }
62        let callback = Some(callback_func::<P> as _);
63        unsafe extern "C" fn destroy_func<
64            P: Fn(&Cursor, i32, f64, &mut i32, &mut i32, &mut i32, &mut i32) -> Texture + 'static,
65        >(
66            data: glib::ffi::gpointer,
67        ) {
68            unsafe {
69                let _callback = Box_::from_raw(data as *mut P);
70            }
71        }
72        let destroy_call2 = Some(destroy_func::<P> as _);
73        let super_callback0: Box_<P> = callback_data;
74        unsafe {
75            from_glib_full(ffi::gdk_cursor_new_from_callback(
76                callback,
77                Box_::into_raw(super_callback0) as *mut _,
78                destroy_call2,
79                fallback.to_glib_none().0,
80            ))
81        }
82    }
83}