add function to extract canvas dimensions from GAM

gfx_conn should be exclusive from GAM to gfx_conn, so
need to refactor out all the errant calls that are
scattered about.
This commit is contained in:
bunnie 2021-03-01 02:33:13 +08:00
parent bee1f796ee
commit ce59bea2fa
4 changed files with 44 additions and 9 deletions

View file

@ -1,5 +1,5 @@
use xous::{Message, ScalarMessage};
use graphics_server::api::{Point, Rectangle, TextView, TextViewResult, Gid};
use graphics_server::api::{Point, Rectangle, TextView, TextViewResult, Gid, Line};
use blitstr_ref as blitstr;
use blitstr::{GlyphStyle, Cursor};
@ -23,6 +23,12 @@ pub enum Opcode {
// indicates if the current UI layout requires an input field
HasInput(bool),
// return the dimensions of a canvas
GetCanvasBounds(Gid),
// draws a line on a canvas
DrawLine(Gid, Line),
}
impl core::convert::TryFrom<&Message> for Opcode {
@ -33,6 +39,10 @@ impl core::convert::TryFrom<&Message> for Opcode {
0 => Ok(Opcode::ClearCanvas(Gid::new([m.arg1 as _, m.arg2 as _, m.arg3 as _, m.arg4 as _]))),
_ => Err("GAM api: unknown Scalar ID"),
},
Message::BlockingScalar(m) => match m.id {
0 => Ok(Opcode::GetCanvasBounds(Gid::new([m.arg1 as _, m.arg2 as _, m.arg3 as _, m.arg4 as _]))),
_ => Err("GAM api: unknown BlockingScalar ID"),
}
_ => Err("GAM api: unhandled message type"),
}
}
@ -44,6 +54,9 @@ impl Into<Message> for Opcode {
Opcode::ClearCanvas(gid) => Message::Scalar(ScalarMessage {
id: 0, arg1: gid.gid()[0] as _, arg2: gid.gid()[1] as _, arg3: gid.gid()[2] as _, arg4: gid.gid()[3] as _
}),
Opcode::GetCanvasBounds(gid) => Message::BlockingScalar(ScalarMessage {
id: 0, arg1: gid.gid()[0] as _, arg2: gid.gid()[1] as _, arg3: gid.gid()[2] as _, arg4: gid.gid()[3] as _
}),
_ => panic!("GAM api: Opcode type not handled by Into(), maybe you meant to use a helper method?"),
}
}

View file

@ -17,10 +17,10 @@ pub fn post_textview(gam_cid: xous::CID, tv: &mut TextView) -> Result<(), xous::
tv.set_op(TextOp::Render);
let mut rkyv_tv = api::Opcode::RenderTextView(*tv);
let mut writer = rkyv::ArchiveBuffer::new(xous::XousBuffer::new(4096));
let pos = writer.archive(&rkyv_tv).expect("couldn't archive textview");
let pos = writer.archive(&rkyv_tv).expect("GAM_API: couldn't archive textview");
let mut xous_buffer = writer.into_inner();
xous_buffer.lend_mut(gam_cid, pos as u32).expect("RenderTextView operation failure");
xous_buffer.lend_mut(gam_cid, pos as u32).expect("GAM_API: RenderTextView operation failure");
// recover the mutable values and mirror the ones we care about back into our local structure
let returned = unsafe { rkyv::archived_value::<api::Opcode>(xous_buffer.as_ref(), pos)};
@ -31,9 +31,20 @@ pub fn post_textview(gam_cid: xous::CID, tv: &mut TextView) -> Result<(), xous::
} else {
let tvr = returned.unarchive();
info!("got {:?}", tvr);
panic!("post_textview got a return value from the server that isn't expected or handled");
panic!("GAM_API: post_textview got a return value from the server that isn't expected or handled");
}
tv.set_op(TextOp::Nop);
Ok(())
}
pub fn get_canvas_bounds(gam_cid: xous::CID, gid: Gid) -> Result<Point, xous::Error> {
let response = xous::send_message(gam_cid, api::Opcode::GetCanvasBounds(gid).into())?;
if let xous::Result::Scalar2(tl, br) = response {
// note that the result should always be normalized so the rectangle's "tl" should be (0,0)
assert!(tl == 0, "GAM_API: api call returned non-zero top left for canvas bounds");
Ok(br.into())
} else {
panic!("GAM_API: can't get canvas bounds")
}
}

View file

@ -160,6 +160,19 @@ fn xmain() -> ! {
None => info!("GAM: attempt to clear bogus canvas, ignored."),
}
},
Opcode::GetCanvasBounds(gid) => {
match canvases.get(&gid) {
Some(c) => {
let mut rect = c.clip_rect();
rect.translate(rect.tl); // normalize to 0,0 coordinates
xous::return_scalar2(envelope.sender,
rect.tl.into(),
rect.br.into(),
).expect("GAM: couldn't return canvas bounds");
},
None => info!("GAM: attempt to get bounds on bogus canvas, ignored."),
}
}
_ => todo!("GAM: opcode not yet implemented"),
}
} else if let xous::Message::MutableBorrow(m) = &envelope.body {

View file

@ -22,15 +22,13 @@ pub fn status_thread(canvas_gid: [u32; 4]) {
let gam_conn = xous_names::request_connection_blocking(xous::names::SERVER_NAME_GAM).expect("GAM|status: can't connect to GAM");
info!("GAM|status: getting screen size");
let screensize = graphics_server::screen_size(gfx_conn).expect("GAM|status: Couldn't get screen size");
info!("GAM|status: getting height hints");
let small_height: i16 = graphics_server::glyph_height_hint(gfx_conn, blitstr::GlyphStyle::Small).expect("GAM|status: couldn't get glyph height") as i16;
let screensize = gam::get_canvas_bounds(gam_conn, status_gid).expect("GAM|status: Couldn't get canvas size");
info!("GAM|status: building textview objects");
// build uptime text view: left half of status bar
let mut uptime_tv = TextView::new(status_gid, 0,
TextBounds::BoundingBox(Rectangle::new(Point::new(0,0),
Point::new(screensize.x / 2, small_height))));
Point::new(screensize.x / 2, screensize.y - 1))));
uptime_tv.untrusted = false;
uptime_tv.style = blitstr::GlyphStyle::Small;
uptime_tv.draw_border = false;
@ -42,7 +40,7 @@ pub fn status_thread(canvas_gid: [u32; 4]) {
// build battstats text view: right half of status bar
let mut battstats_tv = TextView::new(status_gid, 0,
TextBounds::BoundingBox(Rectangle::new(Point::new(screensize.x / 2, 0),
Point::new(screensize.x, small_height))));
Point::new(screensize.x, screensize.y - 1))));
battstats_tv.style = blitstr::GlyphStyle::Small;
battstats_tv.draw_border = false;
battstats_tv.margin = Point::new(0, 0);