mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
Merge branch 'main' of github.com:betrusted-io/xous-core into main
This commit is contained in:
commit
71df3a624b
6 changed files with 113 additions and 3 deletions
|
|
@ -115,6 +115,14 @@ impl TextEntryPayload {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct SliderPayload(pub u32);
|
||||
impl SliderPayload {
|
||||
pub fn new(value: u32) -> Self {
|
||||
SliderPayload(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
|
||||
pub struct RadioButtonPayload(pub ItemName); // returns the name of the item corresponding to the radio button selection
|
||||
impl RadioButtonPayload {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ impl Slider {
|
|||
show_legend,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_is_progressbar(&mut self, setting: bool) {
|
||||
self.is_progressbar = setting;
|
||||
}
|
||||
|
||||
pub fn set_is_password(&mut self, setting: bool) {
|
||||
// this will cause text to be inverted. Untrusted entities can try to set this,
|
||||
// but the GAM should defeat this for dialog boxes outside of the trusted boot
|
||||
|
|
@ -194,8 +199,11 @@ impl ActionApi for Slider {
|
|||
gam.relinquish_focus().unwrap();
|
||||
xous::yield_slice();
|
||||
|
||||
send_message(self.action_conn,
|
||||
xous::Message::new_scalar(self.action_opcode as usize, self.action_payload as usize, 0, 0, 0)).expect("couldn't pass on action payload");
|
||||
let ret_payload = SliderPayload(self.action_payload);
|
||||
|
||||
let buf = Buffer::into_buf(ret_payload).expect("couldn't convert message to payload");
|
||||
buf.send(self.action_conn, self.action_opcode).map(|_| ()).expect("couldn't send action message");
|
||||
|
||||
return None;
|
||||
}
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ pub struct ManagedProgress {
|
|||
pub end_work: u32,
|
||||
/// current quanta of work. Used to int the bar, updates are just a scalar with the same value.
|
||||
pub current_work: u32,
|
||||
/// can user interact with it?
|
||||
pub user_interaction: bool,
|
||||
}
|
||||
|
||||
/// This isn't a terribly useful notification -- it's basically read-only, no interactivity,
|
||||
|
|
@ -98,6 +100,8 @@ pub(crate) enum Opcode {
|
|||
Bip39 = 31, // ---- note op number
|
||||
Bip39Input = 32, // ----- note op number
|
||||
Bip39Return = 33, // ----- note op number
|
||||
SliderReturn = 34,
|
||||
Slider = 35,
|
||||
/// display an image
|
||||
#[cfg(feature = "ditherpunk")]
|
||||
Image = 3,
|
||||
|
|
|
|||
|
|
@ -302,6 +302,7 @@ impl Modals {
|
|||
start_work: start,
|
||||
end_work: end,
|
||||
current_work: current,
|
||||
user_interaction: false,
|
||||
};
|
||||
let buf = Buffer::into_buf(spec).or(Err(xous::Error::InternalError))?;
|
||||
buf.lend(self.conn, Opcode::StartProgress.to_u32().unwrap())
|
||||
|
|
@ -309,6 +310,32 @@ impl Modals {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn slider(
|
||||
&self,
|
||||
title: &str,
|
||||
start: u32,
|
||||
end: u32,
|
||||
current: u32,
|
||||
) -> Result<u32, xous::Error> {
|
||||
self.lock();
|
||||
let spec = ManagedProgress {
|
||||
token: self.token,
|
||||
title: xous_ipc::String::from_str(title),
|
||||
start_work: start,
|
||||
end_work: end,
|
||||
current_work: current,
|
||||
user_interaction: true,
|
||||
};
|
||||
let mut buf = Buffer::into_buf(spec).or(Err(xous::Error::InternalError))?;
|
||||
buf.lend_mut(self.conn, Opcode::Slider.to_u32().unwrap())
|
||||
.or(Err(xous::Error::InternalError))?;
|
||||
|
||||
let orig = buf.to_original::<SliderPayload, _>().unwrap();
|
||||
|
||||
self.unlock();
|
||||
Ok(orig.0)
|
||||
}
|
||||
|
||||
/// note that this API is not atomically token-locked, so, someone could mess with the progress bar state
|
||||
/// but, progress updates are meant to be fast and frequent, and generally if a progress bar shows
|
||||
/// something whacky it's not going to affect a security outcome
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ fn wrapped_main() -> ! {
|
|||
let mut fixed_items = Vec::<ItemName>::new();
|
||||
let mut progress_action = Slider::new(
|
||||
renderer_cid,
|
||||
Opcode::Gutter.to_u32().unwrap(),
|
||||
Opcode::SliderReturn.to_u32().unwrap(),
|
||||
0,
|
||||
100,
|
||||
1,
|
||||
|
|
@ -332,6 +332,24 @@ fn wrapped_main() -> ! {
|
|||
)
|
||||
.expect("couldn't initiate UX op");
|
||||
}
|
||||
Some(Opcode::Slider) => {
|
||||
let spec = {
|
||||
let buffer =
|
||||
unsafe { Buffer::from_memory_message_mut(msg.body.memory_message_mut().unwrap()) };
|
||||
buffer.to_original::<ManagedProgress, _>().unwrap()
|
||||
};
|
||||
if spec.token != token_lock.unwrap_or(default_nonce) {
|
||||
log::warn!("Attempt to access modals without a mutex lock. Ignoring.");
|
||||
continue;
|
||||
}
|
||||
op = RendererState::RunProgress(spec);
|
||||
dr = Some(msg);
|
||||
send_message(
|
||||
renderer_cid,
|
||||
Message::new_scalar(Opcode::InitiateOp.to_usize().unwrap(), 0, 0, 0, 0),
|
||||
)
|
||||
.expect("couldn't initiate UX op");
|
||||
}
|
||||
Some(Opcode::StopProgress) => msg_blocking_scalar_unpack!(msg, t0, t1, t2, t3, {
|
||||
let token = [t0 as u32, t1 as u32, t2 as u32, t3 as u32];
|
||||
if token != token_lock.unwrap_or(default_nonce) {
|
||||
|
|
@ -593,6 +611,7 @@ fn wrapped_main() -> ! {
|
|||
end_work
|
||||
);
|
||||
progress_action.set_state(last_percentage);
|
||||
progress_action.set_is_progressbar(!config.user_interaction);
|
||||
#[cfg(feature = "tts")]
|
||||
tts.tts_simple(config.title.as_str().unwrap()).unwrap();
|
||||
renderer_modal.modify(
|
||||
|
|
@ -603,6 +622,7 @@ fn wrapped_main() -> ! {
|
|||
true,
|
||||
Some(DEFAULT_STYLE),
|
||||
);
|
||||
|
||||
renderer_modal.activate();
|
||||
}
|
||||
RendererState::RunRadio(config) => {
|
||||
|
|
@ -764,6 +784,32 @@ fn wrapped_main() -> ! {
|
|||
xous::return_scalar2(sender, 1, k).unwrap();
|
||||
}
|
||||
}),
|
||||
Some(Opcode::SliderReturn) => match op {
|
||||
RendererState::RunProgress(_) => {
|
||||
let buffer =
|
||||
unsafe { Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
|
||||
let item = buffer.to_original::<SliderPayload, _>().unwrap();
|
||||
|
||||
if let Some(mut origin) = dr.take() {
|
||||
let mut response = unsafe {
|
||||
Buffer::from_memory_message_mut(
|
||||
origin.body.memory_message_mut().unwrap(),
|
||||
)
|
||||
};
|
||||
|
||||
response.replace(item).unwrap();
|
||||
op = RendererState::None;
|
||||
|
||||
token_lock = next_lock(&mut work_queue);
|
||||
} else {
|
||||
log::error!("Ux routine returned but no origin was recorded");
|
||||
panic!("Ux routine returned but no origin was recorded");
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
log::warn!("got weird stuff on slider return, ignoring");
|
||||
}
|
||||
},
|
||||
Some(Opcode::TextEntryReturn) => match op {
|
||||
RendererState::RunText(_config) => {
|
||||
log::trace!("validating text entry modal");
|
||||
|
|
|
|||
|
|
@ -96,6 +96,20 @@ pub fn spawn_test() {
|
|||
}
|
||||
Err(e) => log::error!("couldn't get input: {:?}", e),
|
||||
}
|
||||
|
||||
// 6. human interaction-enabled slider
|
||||
log::info!("testing human interaction-enabled slider");
|
||||
let result = modals.slider(
|
||||
"Human interaction-enabled slider!",
|
||||
0,
|
||||
100,
|
||||
50,
|
||||
).expect("slider test failed");
|
||||
|
||||
modals.show_notification(&format!("Slider value: {}", result), None)
|
||||
.expect("cannot show slider result notification");
|
||||
|
||||
log::info!("slider test done");
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -165,6 +179,9 @@ pub fn spawn_test() {
|
|||
modals.show_image(bm).expect("show image modal failed");
|
||||
log::info!("image modal test done");
|
||||
}
|
||||
|
||||
// 6. test that human-interactable slider modal
|
||||
log::info!("testing human interaction-enabled modal");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue