feat(display): input routed via display server to focused app; input Subscribe; uses caps badged + Delegate
This commit is contained in:
@@ -27,6 +27,8 @@ pub(crate) struct Launcher<'a> {
|
||||
devices: Devices,
|
||||
/// The endpoint of every server started so far, by name.
|
||||
served: [Option<(&'static str, CapSlot)>; MAX_SERVED],
|
||||
/// The badge on the next client's endpoint copy (0 is init's own).
|
||||
next_badge: usize,
|
||||
/// Init's own endpoint, for the spawn service.
|
||||
pub(crate) spawn_ep: CapSlot,
|
||||
/// Bound to init's thread: spawned children's deaths, a bit each.
|
||||
@@ -42,7 +44,7 @@ impl<'a> Launcher<'a> {
|
||||
) -> Result<Self, &'static str> {
|
||||
let spawn_ep = syscall::create_endpoint().ok_or("no spawn endpoint")?;
|
||||
let deaths = syscall::create_notification().map_err(|_| "no death notification")?;
|
||||
Ok(Self { storage, scratch, devices, served: [None; MAX_SERVED], spawn_ep, deaths, spawner: Spawner::new() })
|
||||
Ok(Self { storage, scratch, devices, served: [None; MAX_SERVED], next_badge: 1, spawn_ep, deaths, spawner: Spawner::new() })
|
||||
}
|
||||
|
||||
pub(crate) fn storage(&mut self) -> (&mut Storage, &mut [u8]) {
|
||||
@@ -68,11 +70,18 @@ impl<'a> Launcher<'a> {
|
||||
}
|
||||
false => None,
|
||||
};
|
||||
// A client only calls: Execute, never Read, so it cannot pose as the
|
||||
// server and take other clients' requests.
|
||||
// A client calls (Execute) and may send capabilities through it and
|
||||
// pass it on (Delegate); never Read, so it cannot pose as the server
|
||||
// and take other clients' requests.
|
||||
for name in p.uses {
|
||||
let ep = self.endpoint(name).ok_or("needs a server that is not running")?;
|
||||
syscall::delegate(ep, child, perms(&[Permission::Execute])).ok_or("cannot give an endpoint")?;
|
||||
let badge = Badge::new(self.next_badge);
|
||||
self.next_badge += 1;
|
||||
let copy = syscall::mint(ep, badge, perms(&[Permission::Execute, Permission::Delegate]))
|
||||
.map_err(|_| "cannot mint an endpoint")?;
|
||||
let given = syscall::delegate(copy, child, perms(&[Permission::Execute, Permission::Delegate]));
|
||||
syscall::drop_cap(copy);
|
||||
given.ok_or("cannot give an endpoint")?;
|
||||
}
|
||||
if let Some(allowance) = p.spawns {
|
||||
self.give_spawn(child, allowance)?;
|
||||
|
||||
@@ -16,7 +16,8 @@ pub struct Program {
|
||||
/// Serves an endpoint, which it finds in slot 0.
|
||||
pub serves: bool,
|
||||
pub device: Option<Device>,
|
||||
/// Earlier programs' endpoints it may call, in its next slots.
|
||||
/// Earlier programs' endpoints it may call, in its next slots; each
|
||||
/// program's copy carries its own badge, so a server can tell them apart.
|
||||
pub uses: &'static [&'static str],
|
||||
/// Takes the console over from init; everyone else prints through it.
|
||||
pub console: bool,
|
||||
@@ -51,12 +52,14 @@ const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Prog
|
||||
/// Started on every boot. The log server comes first so the rest can print.
|
||||
pub const SERVERS: &[Program] = &[
|
||||
Program { console: true, ..server("log", b"log.elf", SMALL) },
|
||||
Program { device: Some(Device::Input), ..server("input", b"input.elf", Limits { regions: 4, ..SMALL }) },
|
||||
// The input server's only client: it passes input on to the app in focus.
|
||||
Program {
|
||||
device: Some(Device::Gpu),
|
||||
uses: &["input"],
|
||||
// The framebuffer alone is ~1000 pages at 1280x800.
|
||||
..server("display", b"display.elf", Limits { pages: 1280, regions: 4, ..SMALL })
|
||||
},
|
||||
Program { device: Some(Device::Input), ..server("input", b"input.elf", Limits { regions: 4, ..SMALL }) },
|
||||
server("permis", b"permis.elf", SMALL),
|
||||
server("session", b"session.elf", SMALL),
|
||||
];
|
||||
@@ -73,6 +76,6 @@ pub const TESTS: &[Program] = &[Program {
|
||||
/// The desktop; the test image runs the SMP self-test instead.
|
||||
pub const APPS: &[Program] = &[Program {
|
||||
serves: false,
|
||||
uses: &["input", "display"],
|
||||
uses: &["display"],
|
||||
..server("snake", b"snake.elf", Limits { pages: 128, ..SMALL })
|
||||
}];
|
||||
|
||||
Reference in New Issue
Block a user