Merge branch 'vt_to_go' into 'master'
Implicitly create a new VT for each consumer See merge request redox-os/drivers!244
This commit is contained in:
@@ -46,7 +46,7 @@ pub struct Display {
|
||||
|
||||
impl Display {
|
||||
pub fn open_first_vt() -> io::Result<Self> {
|
||||
let input_handle = ConsumerHandle::for_vt(1)?;
|
||||
let input_handle = ConsumerHandle::new_vt()?;
|
||||
|
||||
let map = match input_handle.open_display() {
|
||||
Ok(display) => {
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct DisplayMap {
|
||||
|
||||
impl Display {
|
||||
pub fn open_vt(vt: usize) -> io::Result<Self> {
|
||||
let input_handle = ConsumerHandle::for_vt(vt)?;
|
||||
let input_handle = ConsumerHandle::new_vt()?;
|
||||
|
||||
if let Ok(display_handle) = Self::open_display(&input_handle) {
|
||||
let map = display_handle
|
||||
|
||||
@@ -15,12 +15,6 @@ mod framebuffer;
|
||||
mod scheme;
|
||||
|
||||
fn main() {
|
||||
let mut spec = Vec::new();
|
||||
|
||||
for _ in env::args().skip(1) {
|
||||
spec.push(());
|
||||
}
|
||||
|
||||
if env::var("FRAMEBUFFER_WIDTH").is_err() {
|
||||
println!("vesad: No boot framebuffer");
|
||||
return;
|
||||
@@ -78,16 +72,12 @@ fn main() {
|
||||
};
|
||||
}
|
||||
|
||||
redox_daemon::Daemon::new(|daemon| inner(daemon, framebuffers, &spec))
|
||||
redox_daemon::Daemon::new(|daemon| inner(daemon, framebuffers))
|
||||
.expect("failed to create daemon");
|
||||
}
|
||||
fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec<FrameBuffer>, spec: &[()]) -> ! {
|
||||
fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec<FrameBuffer>) -> ! {
|
||||
let mut inputd_display_handle = DisplayHandle::new_early("vesa").unwrap();
|
||||
|
||||
for &() in spec.iter() {
|
||||
inputd_display_handle.register_vt().unwrap();
|
||||
}
|
||||
|
||||
let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned());
|
||||
|
||||
user_data! {
|
||||
|
||||
+2
-8
@@ -17,11 +17,11 @@ unsafe fn any_as_u8_slice_mut<T: Sized>(p: &mut T) -> &mut [u8] {
|
||||
pub struct ConsumerHandle(File);
|
||||
|
||||
impl ConsumerHandle {
|
||||
pub fn for_vt(vt: usize) -> Result<Self, Error> {
|
||||
pub fn new_vt() -> Result<Self, Error> {
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.custom_flags(O_NONBLOCK as i32)
|
||||
.open(format!("/scheme/input/consumer/{vt}"))?;
|
||||
.open(format!("/scheme/input/consumer"))?;
|
||||
Ok(Self(file))
|
||||
}
|
||||
|
||||
@@ -70,12 +70,6 @@ impl DisplayHandle {
|
||||
Ok(Self(File::open(path)?))
|
||||
}
|
||||
|
||||
// The return value is the display identifier. It will be used to uniquely
|
||||
// identify the display on activation events.
|
||||
pub fn register_vt(&mut self) -> Result<usize, Error> {
|
||||
self.0.read(&mut [])
|
||||
}
|
||||
|
||||
pub fn read_vt_event(&mut self) -> Result<Option<VtEvent>, Error> {
|
||||
let mut event = VtEvent {
|
||||
kind: VtEventKind::Resize,
|
||||
|
||||
+25
-24
@@ -131,17 +131,19 @@ impl Scheme for InputScheme {
|
||||
let handle_ty = match command {
|
||||
"producer" => Handle::Producer,
|
||||
"consumer" => {
|
||||
let target = path_parts
|
||||
.next()
|
||||
.and_then(|x| x.parse::<usize>().ok())
|
||||
.ok_or(SysError::new(EINVAL))?;
|
||||
let vt = self.next_vt_id.fetch_add(1, Ordering::Relaxed);
|
||||
self.vts.insert(vt);
|
||||
|
||||
if self.active_vt.is_none() {
|
||||
self.switch_vt(vt);
|
||||
}
|
||||
|
||||
Handle::Consumer {
|
||||
events: EventFlags::empty(),
|
||||
pending: Vec::new(),
|
||||
needs_handoff: false,
|
||||
notified: false,
|
||||
vt: target,
|
||||
vt,
|
||||
}
|
||||
}
|
||||
"handle" | "handle_early" => {
|
||||
@@ -258,24 +260,8 @@ impl Scheme for InputScheme {
|
||||
Ok(copy)
|
||||
}
|
||||
|
||||
Handle::Display {
|
||||
pending, device, ..
|
||||
} => {
|
||||
// FIXME Create new VT through a write instead and return a NewVt event on read
|
||||
// This allows also returning events for VT (de)activation from the display handle
|
||||
// rather than pushing them to the graphics driver.
|
||||
if buf.is_empty() {
|
||||
// Trying to do an empty read creates a new VT.
|
||||
let vt = self.next_vt_id.fetch_add(1, Ordering::SeqCst);
|
||||
log::info!("inputd: created VT #{vt} for {device}");
|
||||
self.vts.insert(vt);
|
||||
|
||||
if self.active_vt.is_none() {
|
||||
self.switch_vt(vt);
|
||||
}
|
||||
|
||||
Ok(vt)
|
||||
} else if buf.len() % size_of::<VtEvent>() == 0 {
|
||||
Handle::Display { pending, .. } => {
|
||||
if buf.len() % size_of::<VtEvent>() == 0 {
|
||||
let copy = core::cmp::min(pending.len(), buf.len() / size_of::<VtEvent>());
|
||||
|
||||
for (i, event) in pending.drain(..copy).enumerate() {
|
||||
@@ -472,7 +458,22 @@ impl Scheme for InputScheme {
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&mut self, _id: usize) -> syscall::Result<usize> {
|
||||
fn close(&mut self, id: usize) -> syscall::Result<usize> {
|
||||
let handle = self.handles.get(&id).ok_or(SysError::new(EINVAL))?;
|
||||
|
||||
match *handle {
|
||||
Handle::Consumer { vt, .. } => {
|
||||
self.vts.remove(&vt);
|
||||
if self.active_vt == Some(vt) {
|
||||
if let Some(&new_vt) = self.vts.last() {
|
||||
self.switch_vt(new_vt);
|
||||
} else {
|
||||
self.active_vt = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user