pub mod canvas;
use core::ffi::CStr;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
use core::ptr;
use canvas::Canvas;
use flipperzero_sys as sys;
use flipperzero_sys::furi::UnsafeRecord;
pub struct Gui {
record: UnsafeRecord<sys::Gui>,
}
impl Gui {
const NAME: &CStr = c"gui";
pub fn open() -> Self {
Self {
record: unsafe { UnsafeRecord::open(Self::NAME) },
}
}
#[inline]
pub fn as_ptr(&self) -> *mut sys::Gui {
self.record.as_ptr()
}
pub fn get_framebuffer_size(&self) -> usize {
unsafe { sys::gui_get_framebuffer_size(self.as_ptr()) }
}
pub fn set_lockdown(&self, lockdown: bool) {
unsafe { sys::gui_set_lockdown(self.as_ptr(), lockdown) }
}
pub fn direct_draw_acquire(&self) -> ExclusiveCanvas<'_> {
ExclusiveCanvas::new(self)
}
}
pub struct ExclusiveCanvas<'a> {
gui: &'a Gui,
canvas: ptr::NonNull<sys::Canvas>,
_marker: PhantomData<&'a mut Canvas>,
}
impl<'a> ExclusiveCanvas<'a> {
fn new(gui: &'a Gui) -> Self {
ExclusiveCanvas {
gui,
canvas: unsafe {
ptr::NonNull::new_unchecked(sys::gui_direct_draw_acquire(gui.as_ptr()))
},
_marker: PhantomData,
}
}
pub fn canvas(&self) -> &Canvas {
unsafe { Canvas::from_raw(self.canvas.as_ptr()) }
}
pub fn canvas_mut(&mut self) -> &mut Canvas {
unsafe { Canvas::from_raw_mut(self.canvas.as_ptr()) }
}
}
impl Deref for ExclusiveCanvas<'_> {
type Target = Canvas;
fn deref(&self) -> &Self::Target {
self.canvas()
}
}
impl DerefMut for ExclusiveCanvas<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.canvas_mut()
}
}
impl Drop for ExclusiveCanvas<'_> {
fn drop(&mut self) {
unsafe { sys::gui_direct_draw_release(self.gui.as_ptr()) }
}
}