2025-12-29 19:36:00 +01:00
|
|
|
// #![cfg_attr(not(feature = "simulator"), no_main)]
|
|
|
|
|
|
2026-01-20 02:55:17 +01:00
|
|
|
use alloc::{boxed::Box, ffi::CString};
|
|
|
|
|
use log::{info, warn};
|
|
|
|
|
use slint::SharedString;
|
|
|
|
|
use spectre_api_sys::{SpectreAlgorithm, SpectreCounter, SpectreKeyPurpose, SpectreUserKey};
|
2026-01-10 19:21:13 +01:00
|
|
|
|
|
|
|
|
#[cfg(feature = "limit-fps")]
|
|
|
|
|
use crate::FRAME_DURATION_MIN;
|
2026-01-20 02:55:17 +01:00
|
|
|
use crate::{SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER, ui::backend::SlintBackend};
|
2026-01-10 19:21:13 +01:00
|
|
|
|
2025-12-31 22:24:26 +01:00
|
|
|
pub mod backend;
|
2026-01-10 19:21:13 +01:00
|
|
|
pub mod window_adapter;
|
2025-12-31 22:24:26 +01:00
|
|
|
|
2025-12-29 19:36:00 +01:00
|
|
|
slint::include_modules!();
|
2026-01-10 19:21:13 +01:00
|
|
|
|
|
|
|
|
#[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();
|
|
|
|
|
|
2026-01-20 02:55:17 +01:00
|
|
|
let mut buffer = CString::default();
|
|
|
|
|
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 = &*spectre_api_sys::spectre_user_key(
|
|
|
|
|
c"test".as_ptr(),
|
|
|
|
|
c_string.as_ptr(),
|
|
|
|
|
SpectreAlgorithm::Current,
|
|
|
|
|
);
|
|
|
|
|
warn!("{user_key:?}");
|
|
|
|
|
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(),
|
|
|
|
|
);
|
|
|
|
|
warn!("{site_key:?}");
|
|
|
|
|
|
|
|
|
|
// TODO: Free memory
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-01-10 19:21:13 +01:00
|
|
|
// 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();
|
|
|
|
|
}
|
|
|
|
|
}
|