1use capsules_extra::screen::screen::Screen;
34use capsules_extra::screen::screen_shared::ScreenShared;
35use capsules_extra::virtualizers::screen::virtual_screen_split;
36use core::mem::MaybeUninit;
37use kernel::capabilities;
38use kernel::component::Component;
39use kernel::create_capability;
40use kernel::hil;
41
42#[macro_export]
43macro_rules! screen_split_mux_component_static {
44 ($S:ty $(,)?) => {{
45 kernel::static_buf!(
46 capsules_extra::virtualizers::screen::virtual_screen_split::ScreenSplitMux<'static, $S>
47 )
48 };};
49}
50
51#[macro_export]
52macro_rules! screen_split_user_component_static {
53 ($S:ty $(,)?) => {{
54 kernel::static_buf!(
55 capsules_extra::virtualizers::screen::virtual_screen_split::ScreenSplitUser<
56 'static,
57 $S,
58 >
59 )
60 };};
61}
62
63pub type ScreenSplitMuxComponentType<S> = virtual_screen_split::ScreenSplitMux<'static, S>;
64
65pub struct ScreenSplitMuxComponent<S: hil::screen::Screen<'static> + 'static> {
66 screen: &'static S,
67}
68
69impl<S: hil::screen::Screen<'static>> ScreenSplitMuxComponent<S> {
70 pub fn new(screen: &'static S) -> Self {
71 Self { screen }
72 }
73}
74
75impl<S: hil::screen::Screen<'static> + 'static> Component for ScreenSplitMuxComponent<S> {
76 type StaticInput = &'static mut MaybeUninit<virtual_screen_split::ScreenSplitMux<'static, S>>;
77 type Output = &'static virtual_screen_split::ScreenSplitMux<'static, S>;
78
79 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
80 let mux = static_input.write(virtual_screen_split::ScreenSplitMux::new(self.screen));
81
82 kernel::hil::screen::Screen::set_client(self.screen, mux);
83 kernel::deferred_call::DeferredCallClient::register(mux);
84
85 mux
86 }
87}
88
89pub type ScreenSplitUserComponentType<S> = virtual_screen_split::ScreenSplitUser<'static, S>;
90
91pub struct ScreenSplitUserComponent<S: hil::screen::Screen<'static> + 'static> {
92 mux: &'static virtual_screen_split::ScreenSplitMux<'static, S>,
93 x: usize,
94 y: usize,
95 width: usize,
96 height: usize,
97}
98
99impl<S: hil::screen::Screen<'static>> ScreenSplitUserComponent<S> {
100 pub fn new(
101 mux: &'static virtual_screen_split::ScreenSplitMux<'static, S>,
102 x: usize,
103 y: usize,
104 width: usize,
105 height: usize,
106 ) -> Self {
107 Self {
108 mux,
109 x,
110 y,
111 width,
112 height,
113 }
114 }
115}
116
117impl<S: hil::screen::Screen<'static> + 'static> Component for ScreenSplitUserComponent<S> {
118 type StaticInput = &'static mut MaybeUninit<virtual_screen_split::ScreenSplitUser<'static, S>>;
119 type Output = &'static virtual_screen_split::ScreenSplitUser<'static, S>;
120
121 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
122 let split = static_input.write(virtual_screen_split::ScreenSplitUser::new(
123 self.mux,
124 self.x,
125 self.y,
126 self.width,
127 self.height,
128 ));
129
130 split.add_to_mux();
131
132 split
133 }
134}
135
136#[macro_export]
137macro_rules! screen_component_static {
138 ($s:literal $(,)?) => {{
139 let buffer = kernel::static_buf!([u8; $s]);
140 let screen = kernel::static_buf!(capsules_extra::screen::screen::Screen);
141
142 (buffer, screen)
143 };};
144}
145
146pub type ScreenComponentType = capsules_extra::screen::screen::Screen<'static>;
147
148pub struct ScreenComponent<const SCREEN_BUF_LEN: usize> {
149 board_kernel: &'static kernel::Kernel,
150 driver_num: usize,
151 screen: &'static dyn kernel::hil::screen::Screen<'static>,
152 screen_setup: Option<&'static dyn kernel::hil::screen::ScreenSetup<'static>>,
153}
154
155impl<const SCREEN_BUF_LEN: usize> ScreenComponent<SCREEN_BUF_LEN> {
156 pub fn new(
157 board_kernel: &'static kernel::Kernel,
158 driver_num: usize,
159 screen: &'static dyn kernel::hil::screen::Screen,
160 screen_setup: Option<&'static dyn kernel::hil::screen::ScreenSetup>,
161 ) -> ScreenComponent<SCREEN_BUF_LEN> {
162 ScreenComponent {
163 board_kernel,
164 driver_num,
165 screen,
166 screen_setup,
167 }
168 }
169}
170
171impl<const SCREEN_BUF_LEN: usize> Component for ScreenComponent<SCREEN_BUF_LEN> {
172 type StaticInput = (
173 &'static mut MaybeUninit<[u8; SCREEN_BUF_LEN]>,
174 &'static mut MaybeUninit<Screen<'static>>,
175 );
176 type Output = &'static Screen<'static>;
177
178 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
179 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
180 let grant_screen = self.board_kernel.create_grant(self.driver_num, &grant_cap);
181
182 let buffer = static_input.0.write([0; SCREEN_BUF_LEN]);
183
184 let screen = static_input.1.write(Screen::new(
185 self.screen,
186 self.screen_setup,
187 buffer,
188 grant_screen,
189 ));
190
191 kernel::hil::screen::Screen::set_client(self.screen, screen);
192 if let Some(screen_setup) = self.screen_setup {
193 kernel::hil::screen::ScreenSetup::set_client(screen_setup, screen);
194 }
195
196 screen
197 }
198}
199
200#[macro_export]
201macro_rules! screen_shared_component_static {
202 ($s:literal, $S:ty $(,)?) => {{
203 let buffer = kernel::static_buf!([u8; $s]);
204 let screen = kernel::static_buf!(capsules_extra::screen::screen_shared::ScreenShared<$S>);
205
206 (buffer, screen)
207 };};
208}
209
210pub type ScreenSharedComponentType<S> =
211 capsules_extra::screen::screen_shared::ScreenShared<'static, S>;
212
213pub struct ScreenSharedComponent<
214 const SCREEN_BUF_LEN: usize,
215 S: hil::screen::Screen<'static> + 'static,
216> {
217 board_kernel: &'static kernel::Kernel,
218 driver_num: usize,
219 screen: &'static S,
220 apps_regions: &'static [capsules_extra::screen::screen_shared::AppScreenRegion],
221}
222
223impl<const SCREEN_BUF_LEN: usize, S: hil::screen::Screen<'static>>
224 ScreenSharedComponent<SCREEN_BUF_LEN, S>
225{
226 pub fn new(
227 board_kernel: &'static kernel::Kernel,
228 driver_num: usize,
229 screen: &'static S,
230 apps_regions: &'static [capsules_extra::screen::screen_shared::AppScreenRegion],
231 ) -> ScreenSharedComponent<SCREEN_BUF_LEN, S> {
232 ScreenSharedComponent {
233 board_kernel,
234 driver_num,
235 screen,
236 apps_regions,
237 }
238 }
239}
240
241impl<const SCREEN_BUF_LEN: usize, S: hil::screen::Screen<'static>> Component
242 for ScreenSharedComponent<SCREEN_BUF_LEN, S>
243{
244 type StaticInput = (
245 &'static mut MaybeUninit<[u8; SCREEN_BUF_LEN]>,
246 &'static mut MaybeUninit<ScreenShared<'static, S>>,
247 );
248 type Output = &'static ScreenShared<'static, S>;
249
250 fn finalize(self, static_input: Self::StaticInput) -> Self::Output {
251 let grant_cap = create_capability!(capabilities::MemoryAllocationCapability);
252 let grant_screen = self.board_kernel.create_grant(self.driver_num, &grant_cap);
253
254 let buffer = static_input.0.write([0; SCREEN_BUF_LEN]);
255
256 let screen = static_input.1.write(ScreenShared::new(
257 self.screen,
258 grant_screen,
259 buffer,
260 self.apps_regions,
261 ));
262
263 kernel::hil::screen::Screen::set_client(self.screen, screen);
264
265 screen
266 }
267}