Commit a0c5ab79 authored by Jeremy Soller's avatar Jeremy Soller

WIP: VBox resize

parent 83dbbe2c
use syscall::io::{Io, Pio};
const BGA_INDEX_XRES: u16 = 1;
const BGA_INDEX_YRES: u16 = 2;
const BGA_INDEX_BPP: u16 = 3;
const BGA_INDEX_ENABLE: u16 = 4;
pub struct Bga {
index: Pio<u16>,
data: Pio<u16>,
}
impl Bga {
pub fn new() -> Bga {
Bga {
index: Pio::new(0x1CE),
data: Pio::new(0x1CF),
}
}
fn read(&mut self, index: u16) -> u16 {
self.index.write(index);
self.data.read()
}
fn write(&mut self, index: u16, data: u16) {
self.index.write(index);
self.data.write(data);
}
pub fn width(&mut self) -> u16 {
self.read(BGA_INDEX_XRES)
}
pub fn height(&mut self) -> u16 {
self.read(BGA_INDEX_YRES)
}
pub fn set_size(&mut self, width: u16, height: u16) {
self.write(BGA_INDEX_ENABLE, 0);
self.write(BGA_INDEX_XRES, width);
self.write(BGA_INDEX_YRES, height);
self.write(BGA_INDEX_BPP, 32);
self.write(BGA_INDEX_ENABLE, 0x41);
}
}
\ No newline at end of file
......@@ -13,6 +13,10 @@ use syscall::flag::MAP_WRITE;
use syscall::io::{Dma, Io, Mmio, Pio};
use syscall::iopl;
use bga::Bga;
mod bga;
const VBOX_REQUEST_HEADER_VERSION: u32 = 0x10001;
const VBOX_VMMDEV_VERSION: u32 = 0x00010003;
......@@ -234,6 +238,7 @@ fn main() {
let mut event_queue = EventQueue::<()>::new().expect("vboxd: failed to create event queue");
let mut bga = Bga::new();
let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse");
let display_change = VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange");
let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents");
......@@ -247,14 +252,27 @@ fn main() {
if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY {
port.write(display_change.physical() as u32);
println!("Display {}, {}", display_change.xres.read(), display_change.yres.read());
if let Some(ref mut display) = display_opt {
let new_width = display_change.xres.read();
let new_height = display_change.yres.read();
if width != new_width || height != new_height {
width = new_width;
height = new_height;
println!("Display {}, {}", width, height);
bga.set_size(width as u16, height as u16);
let _ = display.write(&orbclient::ResizeEvent {
width: width,
height: height,
}.to_event());
}
}
}
if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE {
port.write(get_mouse.physical() as u32);
let x = get_mouse.x.read() * width / 0x10000;
let y = get_mouse.y.read() * height / 0x10000;
if let Some(ref mut display) = display_opt {
let x = get_mouse.x.read() * width / 0x10000;
let y = get_mouse.y.read() * height / 0x10000;
let _ = display.write(&orbclient::MouseEvent {
x: x as i32,
y: y as i32,
......
......@@ -68,6 +68,36 @@ impl Display {
}
}
pub fn resize(&mut self, width: usize, height: usize) {
println!("Resize display to {}, {}", width, height);
let size = width * height;
let offscreen = unsafe { heap::allocate(size * 4, 4096) };
{
let mut old_ptr = self.offscreen.as_ptr();
let mut new_ptr = offscreen as *mut u32;
for _y in 0..cmp::min(height, self.height) {
unsafe {
fast_copy(new_ptr as *mut u8, old_ptr as *const u8, cmp::min(width, self.width) * 4);
old_ptr = old_ptr.offset(self.width as isize);
new_ptr = new_ptr.offset(width as isize);
}
}
}
self.width = width;
self.height = height;
let onscreen = self.onscreen.as_mut_ptr();
self.onscreen = unsafe { slice::from_raw_parts_mut(onscreen, size) };
unsafe { heap::deallocate(self.offscreen.as_mut_ptr() as *mut u8, self.offscreen.len() * 4, 4096) };
self.offscreen = unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) };
self.sync(0, 0, width, height);
}
/// Draw a rectangle
pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) {
let start_y = cmp::min(self.height - 1, y);
......@@ -244,3 +274,9 @@ impl Display {
}
}
}
impl Drop for Display {
fn drop(&mut self) {
unsafe { heap::deallocate(self.offscreen.as_mut_ptr() as *mut u8, self.offscreen.len() * 4, 4096) };
}
}
......@@ -55,8 +55,9 @@ fn main() {
let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
let size = width * height;
let onscreen = unsafe { physmap(physbaseptr, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
//TODO: Remap on resize
let largest_size = 8 * 1024 * 1024;
let onscreen = unsafe { physmap(physbaseptr, largest_size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };
let mut scheme = DisplayScheme::new(width, height, onscreen, &spec);
......
......@@ -142,21 +142,27 @@ impl SchemeMut for DisplayScheme {
let events = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Event, buf.len()/mem::size_of::<Event>()) };
for event in events.iter() {
let new_active_opt = if let EventOption::Key(key_event) = event.to_option() {
match key_event.scancode {
let mut new_active_opt = None;
match event.to_option() {
EventOption::Key(key_event) => match key_event.scancode {
f @ 0x3B ... 0x44 => { // F1 through F10
Some((f - 0x3A) as usize)
new_active_opt = Some((f - 0x3A) as usize);
},
0x57 => { // F11
Some(11)
new_active_opt = Some(11);
},
0x58 => { // F12
Some(12)
new_active_opt = Some(12);
},
_ => None
}
} else {
None
_ => ()
},
EventOption::Resize(resize_event) => {
println!("Resizing to {}, {}", resize_event.width, resize_event.height);
for (_screen_id, screen) in self.screens.iter_mut() {
screen.resize(resize_event.width as usize, resize_event.height as usize);
}
},
_ => ()
};
if let Some(new_active) = new_active_opt {
......
use std::collections::VecDeque;
use std::{cmp, mem, slice};
use orbclient::Event;
use orbclient::{Event, ResizeEvent};
use syscall::error::*;
use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END};
......@@ -36,6 +36,15 @@ impl Screen for GraphicScreen {
self.display.height
}
fn resize(&mut self, width: usize, height: usize) {
//TODO: Fix issue with mapped screens
self.display.resize(width, height);
self.input.push_back(ResizeEvent {
width: width as u32,
height: height as u32,
}.to_event());
}
fn event(&mut self, flags: usize) -> Result<usize> {
self.requested = flags;
Ok(0)
......
......@@ -12,6 +12,8 @@ pub trait Screen {
fn height(&self) -> usize;
fn resize(&mut self, width: usize, height: usize);
fn event(&mut self, flags: usize) -> Result<usize>;
fn map(&self, offset: usize, size: usize) -> Result<usize>;
......
......@@ -43,6 +43,10 @@ impl Screen for TextScreen {
self.console.h
}
fn resize(&mut self, width: usize, height: usize) {
self.display.resize(width, height);
}
fn event(&mut self, flags: usize) -> Result<usize> {
self.requested = flags;
Ok(0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment