use core::ffi::CStr;
use bitflags::bitflags;
use flipperzero_sys as sys;
use flipperzero_sys::furi::UnsafeRecord;
pub mod backlight;
pub mod feedback;
pub mod led;
pub mod messages;
pub mod sounds;
pub mod vibro;
#[derive(Clone)]
pub struct NotificationApp {
record: UnsafeRecord<sys::NotificationApp>,
}
impl NotificationApp {
pub const NAME: &CStr = c"notification";
pub fn open() -> Self {
Self {
record: unsafe { UnsafeRecord::open(Self::NAME) },
}
}
#[inline]
pub fn as_ptr(&self) -> *mut sys::NotificationApp {
self.record.as_ptr()
}
pub fn notify(&mut self, sequence: &'static NotificationSequence) {
unsafe { sys::notification_message(self.as_ptr(), sequence.to_sys()) };
}
pub fn notify_blocking(&mut self, sequence: &'static NotificationSequence) {
unsafe { sys::notification_message_block(self.as_ptr(), sequence.to_sys()) };
}
}
bitflags! {
pub struct Light: u8 {
const OFF = 0;
const RED = 0b0001;
const GREEN = 0b0010;
const BLUE = 0b0100;
const BACKLIGHT = 0b1000;
const CYAN = Self::GREEN.bits() | Self::BLUE.bits();
const MAGENTA = Self::RED.bits() | Self::BLUE.bits();
const YELLOW = Self::RED.bits() | Self::GREEN.bits();
const WHITE = Self::RED.bits() | Self::GREEN.bits() | Self::BLUE.bits();
}
}
impl Light {
pub const fn to_sys(self) -> sys::Light {
sys::Light(self.bits())
}
}
#[repr(transparent)]
pub struct NotificationMessage(pub(super) sys::NotificationMessage);
impl NotificationMessage {
pub const fn vibro(on: bool) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeVibro,
data: sys::NotificationMessageData {
vibro: sys::NotificationMessageDataVibro { on },
},
})
}
pub const fn sound_on(frequency: f32, volume: f32) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeSoundOn,
data: sys::NotificationMessageData {
sound: sys::NotificationMessageDataSound { frequency, volume },
},
})
}
pub const fn sound_off() -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeSoundOff,
data: sys::NotificationMessageData {
sound: sys::NotificationMessageDataSound {
frequency: 0.0,
volume: 0.0,
},
},
})
}
pub const fn led_red(value: u8) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedRed,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value },
},
})
}
pub const fn led_green(value: u8) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedGreen,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value },
},
})
}
pub const fn led_blue(value: u8) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedBlue,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value },
},
})
}
pub const fn led_blink_start(on_time: u16, period: u16, color: Light) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedBlinkStart,
data: sys::NotificationMessageData {
led_blink: sys::NotificationMessageDataLedBlink {
on_time,
period,
color: color.to_sys(),
},
},
})
}
pub const fn led_blink_stop() -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedBlinkStop,
data: sys::NotificationMessageData {
led_blink: sys::NotificationMessageDataLedBlink {
on_time: 0,
period: 0,
color: sys::Light(0),
},
},
})
}
pub const fn led_blink_color(color: Light) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedBlinkColor,
data: sys::NotificationMessageData {
led_blink: sys::NotificationMessageDataLedBlink {
on_time: 0,
period: 0,
color: color.to_sys(),
},
},
})
}
pub const fn delay(length: u32) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeDelay,
data: sys::NotificationMessageData {
delay: sys::NotificationMessageDataDelay { length },
},
})
}
pub const fn display_backlight(brightness: u8) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedDisplayBacklight,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value: brightness },
},
})
}
pub const fn display_backlight_enforce_on() -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedDisplayBacklightEnforceOn,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value: 0xff },
},
})
}
pub const fn display_backlight_enforce_auto() -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeLedDisplayBacklightEnforceAuto,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value: 0x00 },
},
})
}
pub const fn do_not_reset() -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeDoNotReset,
data: sys::NotificationMessageData {
led: sys::NotificationMessageDataLed { value: 0x00 },
},
})
}
pub const fn force_speaker_volume_setting(speaker_volume: f32) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeForceSpeakerVolumeSetting,
data: sys::NotificationMessageData {
forced_settings: sys::NotificationMessageDataForcedSettings {
speaker_volume,
vibro: false,
display_brightness: 0.0,
},
},
})
}
pub const fn force_vibro_setting(vibro: bool) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeForceVibroSetting,
data: sys::NotificationMessageData {
forced_settings: sys::NotificationMessageDataForcedSettings {
speaker_volume: 0.0,
vibro,
display_brightness: 0.0,
},
},
})
}
pub const fn force_display_brightness_setting(display_brightness: f32) -> Self {
Self(sys::NotificationMessage {
type_: sys::NotificationMessageTypeForceDisplayBrightnessSetting,
data: sys::NotificationMessageData {
forced_settings: sys::NotificationMessageDataForcedSettings {
speaker_volume: 0.0,
vibro: false,
display_brightness,
},
},
})
}
}
pub struct NotificationSequence(&'static [*const NotificationMessage]);
impl NotificationSequence {
#[doc(hidden)]
pub const fn construct(sequence: &'static [*const NotificationMessage]) -> Self {
Self(sequence)
}
pub fn to_sys(&self) -> *const sys::NotificationSequence {
self.0.as_ptr() as *const _
}
}
#[macro_export]
macro_rules! notification_sequence {
($($x:expr),+ $(,)?) => {
{
const S: &[*const $crate::notification::NotificationMessage] = &[
$(&$x as *const _),*,
::core::ptr::null()
];
$crate::notification::NotificationSequence::construct(S)
}
};
}