libfprint_rs/device/
callback.rs

1use std::{os::raw::c_int, os::raw::c_void, sync::Arc};
2
3use glib::translate::{FromGlibPtrBorrow, FromGlibPtrNone};
4
5use crate::print::FpPrint;
6
7use super::{FpDevice, UserData};
8
9pub(crate) extern "C" fn fp_enroll_progress<F, T>(
10    device: *mut libfprint_sys::FpDevice,
11    completed_stages: c_int,
12    print: *mut libfprint_sys::FpPrint, // The last scanned print
13    user_data: *mut c_void,
14    error: *mut libfprint_sys::GError,
15) where
16    F: Fn(&FpDevice, i32, Option<FpPrint>, Option<glib::Error>, &Option<T>),
17{
18    // If user data is not null, a callback function was provided
19    if !user_data.is_null() {
20        // We "reconstruct" the UserData from the void pointer
21        // Safety: This pointer is created on FpDevice::enroll_sync, and is only
22        // used here. After the callback is called, the pointer is forgotten. Then
23        // back in FpDevice::enroll_sync, the pointer is dropped. So we are the only
24        // "owners" of the pointer. The user does not have access to this pointer
25        let callback_data: Arc<UserData<F, T>> = unsafe { Arc::from_raw(user_data.cast()) };
26
27        // We borrow the device
28        let device = unsafe { FpDevice::from_glib_borrow(device) };
29        // Convert the raw pointer to a Rust struct
30        let print = match print.is_null() {
31            true => None,
32            false => Some(unsafe { FpPrint::from_glib_none(print) }),
33        };
34
35        let error = match error.is_null() {
36            true => None,
37            false => Some(unsafe { glib::Error::from_glib_none(error.cast()) }),
38        };
39
40        callback_data.callback_enroll(&device, completed_stages, print, error);
41
42        std::mem::forget(callback_data);
43    }
44}
45
46pub(crate) extern "C" fn fp_match_cb<F, T>(
47    device: *mut libfprint_sys::FpDevice,
48    match_print: *mut libfprint_sys::FpPrint,
49    print: *mut libfprint_sys::FpPrint,
50    user_data: *mut c_void,
51    error: *mut libfprint_sys::GError,
52) where
53    F: Fn(&FpDevice, Option<FpPrint>, FpPrint, Option<glib::Error>, &Option<T>),
54{
55    if !user_data.is_null() {
56        // We reconstruct the UserData struct from the pointer
57        // Safety: We are the only ones who have access to the pointer,
58        // which is created either at verify_sync or identify_sync. Either way, the pointer is
59        // forgotten after the callback is called, so we aer the only "owners" of the pointer.
60        let callback_data: Arc<UserData<F, T>> = unsafe { Arc::from_raw(user_data.cast()) };
61
62        let device = unsafe { FpDevice::from_glib_none(device) };
63
64        let match_print = match match_print.is_null() {
65            true => None,
66            false => Some(unsafe { FpPrint::from_glib_none(match_print) }),
67        };
68        let print = unsafe { FpPrint::from_glib_none(print) };
69        let error = match error.is_null() {
70            true => None,
71            false => Some(unsafe { glib::Error::from_glib_none(error.cast()) }),
72        };
73
74        callback_data.callback_match(&device, match_print, print, error);
75    }
76}