// #![cfg_attr(not(feature = "simulator"), no_main)] use alloc::{boxed::Box, ffi::CString}; use embassy_time::{Duration, Instant}; use log::{info, warn}; use slint::SharedString; use spectre_api_sys::{SpectreAlgorithm, SpectreCounter, SpectreKeyPurpose, SpectreUserKey}; #[cfg(feature = "limit-fps")] use crate::FRAME_DURATION_MIN; use crate::{SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER, ui::backend::SlintBackend, util::DurationExt}; pub mod backend; pub mod window_adapter; slint::include_modules!(); #[embassy_executor::task] pub async fn run_renderer_task(backend: SlintBackend) { slint::platform::set_platform(Box::new(backend)).expect("backend already initialized"); let main = AppWindow::new().unwrap(); main.on_accepted(|string| { warn!("Accepted: {string}"); let Ok(c_string) = CString::new(&*string) else { warn!("String cannot be converted to a C string: {string:?}"); return; }; unsafe { let user_key_start = Instant::now(); let user_key = &*spectre_api_sys::spectre_user_key( c"test".as_ptr(), c_string.as_ptr(), SpectreAlgorithm::Current, ); let user_key_duration = Instant::now().duration_since(user_key_start); warn!( "User key derived in {} seconds:\n{user_key:02x?}", user_key_duration.display_as_secs() ); let site_key_start = Instant::now(); let site_key = &*spectre_api_sys::spectre_site_key( user_key as *const SpectreUserKey, c"example.org".as_ptr(), SpectreCounter::Initial, SpectreKeyPurpose::Authentication, c"".as_ptr(), ); let site_key_duration = Instant::now().duration_since(site_key_start); warn!( "Site key derived in {} seconds:\n{site_key:02x?}", site_key_duration.display_as_secs() ); // TODO: Free memory } }); // Instead of having a `loop` in the non-async `SlintBackend::run_event_loop`, we achieve // async by having only one iteration of the loop run, and `await`ing here. // The following block is analogous to `main.run()`. { main.show().unwrap(); loop { slint::run_event_loop().unwrap(); SIGNAL_LCD_SUBMIT.signal(()); #[cfg(feature = "limit-fps")] embassy_time::Timer::after(FRAME_DURATION_MIN).await; SIGNAL_UI_RENDER.wait().await; } #[expect(unreachable_code)] main.hide().unwrap(); } }