1#[cfg(not(keyos))]
5mod hosted;
6pub mod messages;
7
8use std::time::Duration;
9
10#[cfg(not(keyos))]
11pub use hosted::*;
12use server::{CheckedConn, CheckedPermissions, MessageAllowed};
13
14use crate::messages::*;
15
16pub const CAMERA_WIDTH: usize = 480;
18pub const CAMERA_HEIGHT: usize = 480;
19
20const SCREEN_HEIGHT: usize = 800;
22
23pub const CAMERA_MARGIN: usize = SCREEN_HEIGHT - CAMERA_HEIGHT;
26
27#[cfg(keyos)]
28pub const CAMERA_BYTES_PER_PX: usize = 2; #[cfg(not(keyos))]
30pub const CAMERA_BYTES_PER_PX: usize = 4;
31pub const CAMERA_FB_SIZE_BYTES: usize =
32 CAMERA_WIDTH * (CAMERA_HEIGHT + CAMERA_MARGIN * 2) * CAMERA_BYTES_PER_PX;
33
34pub const SERVER_NAME: &str = "os/camera";
35
36#[macro_export]
37macro_rules! use_api {
38 () => {
39 mod camera_permissions {
40 use camera::messages::*;
41 #[derive(Clone, Default, server::Permissions)]
42 #[server_name = "os/camera"]
43 pub struct CameraPermissions;
44 }
45 type CameraApi = camera::CameraApi<camera_permissions::CameraPermissions>;
46 };
47}
48
49#[derive(Default)]
50pub struct CameraApi<P: CheckedPermissions>(CheckedConn<P>);
51
52impl<P: CheckedPermissions> CameraApi<P> {
53 pub fn try_new_with_timeout(timeout: Duration) -> Option<Self> {
54 CheckedConn::try_connect_with_timeout(timeout).map(Self)
55 }
56
57 pub fn subscribe<S>(&self, context: &mut server::ServerContext<S>) -> Result<(), SubscriptionError>
60 where
61 S: server::Server + server::ScalarEventHandler<Frame>,
62 P: MessageAllowed<Subscribe>,
63 {
64 self.0.subscribe_scalar(Subscribe, context)
65 }
66
67 pub fn set_enabled(&self, enabled: bool)
69 where
70 P: MessageAllowed<SetEnabled>,
71 {
72 self.0.send_scalar(SetEnabled(enabled));
73 }
74
75 pub fn notify_visible(&self, visible: bool)
78 where
79 P: MessageAllowed<NotifyVisible>,
80 {
81 self.0.send_scalar(NotifyVisible(visible));
82 }
83
84 pub fn is_enabled(&self) -> bool
85 where
86 P: MessageAllowed<IsEnabled>,
87 {
88 self.0.send_blocking_scalar(IsEnabled)
89 }
90
91 pub fn is_in_use(&self) -> bool
92 where
93 P: MessageAllowed<IsInUse>,
94 {
95 self.0.send_blocking_scalar(IsInUse)
96 }
97
98 pub fn get_params(&self) -> Result<CameraParams, xous::Error>
100 where
101 P: MessageAllowed<GetParams>,
102 {
103 self.0.try_send_blocking_archive(GetParams).map_err(From::from)
104 }
105
106 pub fn set_params(&self, params: CameraParams) -> Result<(), xous::Error>
108 where
109 P: MessageAllowed<SetParams>,
110 {
111 self.0.try_send_archive(SetParams(params))?;
112 Ok(())
113 }
114}
115
116#[cfg(keyos)]
117pub struct Frame(xous::MemoryRange);
118#[cfg(keyos)]
119server::wrapped_scalar!(Frame);
120
121#[cfg(keyos)]
122impl Frame {
123 pub fn new(range: xous::MemoryRange) -> Self { Self(range) }
124
125 pub fn padded_range(&self) -> xous::MemoryRange { self.0 }
126
127 pub fn content(&self) -> xous::MemoryRange {
128 self.0
129 .subrange(
130 CAMERA_WIDTH * CAMERA_MARGIN * CAMERA_BYTES_PER_PX,
131 CAMERA_WIDTH * CAMERA_HEIGHT * CAMERA_BYTES_PER_PX,
132 )
133 .unwrap()
134 }
135}
136
137#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
138pub enum SubscriptionError {
139 OutOfMemory,
140 Other,
141}