add gui in os

This commit is contained in:
Yu Chen 2022-06-18 15:23:16 +08:00
parent 10e1c57b7d
commit 07029a2e5f
20 changed files with 649 additions and 4 deletions

69
os/src/drivers/gpu/mod.rs Normal file
View file

@ -0,0 +1,69 @@
use crate::sync::UPIntrFreeCell;
use alloc::{sync::Arc, vec::Vec};
use core::any::Any;
use embedded_graphics::pixelcolor::Rgb888;
use tinybmp::Bmp;
use virtio_drivers::{VirtIOGpu, VirtIOHeader};
const VIRTIO7: usize = 0x10007000;
pub trait GPUDevice: Send + Sync + Any {
fn update_cursor(&self);
fn getfreambuffer(&self) -> &mut [u8];
fn flush(&self);
}
lazy_static::lazy_static!(
pub static ref GPU_DEVICE: Arc<dyn GPUDevice> = Arc::new(VirtIOGPU::new());
);
pub struct VirtIOGPU {
gpu: UPIntrFreeCell<VirtIOGpu<'static>>,
fb: &'static [u8],
}
static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
impl VirtIOGPU {
pub fn new() -> Self {
unsafe {
let mut virtio = VirtIOGpu::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
let fbuffer = virtio.setup_framebuffer().unwrap();
let len = fbuffer.len();
let ptr = fbuffer.as_mut_ptr();
let fb = core::slice::from_raw_parts_mut(ptr, len);
let bmp = Bmp::<Rgb888>::from_slice(BMP_DATA).unwrap();
let raw = bmp.as_raw();
let mut b = Vec::new();
for i in raw.image_data().chunks(3) {
let mut v = i.to_vec();
b.append(&mut v);
if i == [255, 255, 255] {
b.push(0x0)
} else {
b.push(0xff)
}
}
virtio.setup_cursor(b.as_slice(), 50, 50, 50, 50).unwrap();
Self {
gpu: UPIntrFreeCell::new(virtio),
fb,
}
}
}
}
impl GPUDevice for VirtIOGPU {
fn flush(&self) {
self.gpu.exclusive_access().flush().unwrap();
}
fn getfreambuffer(&self) -> &mut [u8] {
unsafe {
let ptr = self.fb.as_ptr() as *const _ as *mut u8;
core::slice::from_raw_parts_mut(ptr, self.fb.len())
}
}
fn update_cursor(&self) {
}
}

View file

@ -0,0 +1,68 @@
use core::any::Any;
use alloc::{sync::Arc, string::ToString};
use embedded_graphics::{text::Text, prelude::{Size, Point}};
use k210_hal::cache::Uncache;
use virtio_drivers::{VirtIOHeader, VirtIOInput};
use virtio_input_decoder::{Decoder, Key, KeyType};
use crate::{gui::{Button, Component}, sync::UPIntrFreeCell, syscall::PAD};
use super::GPU_DEVICE;
const VIRTIO5: usize = 0x10005000;
const VIRTIO6: usize = 0x10006000;
struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static>>);
pub trait INPUTDevice: Send + Sync + Any {
fn handler_interrupt(&self);
}
lazy_static::lazy_static!(
pub static ref KEYBOARD_DEVICE: Arc<dyn INPUTDevice> = Arc::new(VirtIOINPUT::new(VIRTIO5));
pub static ref MOUSE_DEVICE: Arc<dyn INPUTDevice> = Arc::new(VirtIOINPUT::new(VIRTIO6));
);
impl VirtIOINPUT {
pub fn new(addr: usize) -> Self {
Self(unsafe {
UPIntrFreeCell::new(VirtIOInput::new(&mut *(addr as *mut VirtIOHeader)).unwrap())
})
}
}
impl INPUTDevice for VirtIOINPUT {
fn handler_interrupt(&self) {
let mut input = self.0.exclusive_access();
input.ack_interrupt();
let event = input.pop_pending_event().unwrap();
let dtype = match Decoder::decode(
event.event_type as usize,
event.code as usize,
event.value as usize,
) {
Ok(dtype) => dtype,
Err(_) => return,
};
match dtype {
virtio_input_decoder::DecodeType::Key(key, r#type) => {
println!("{:?} {:?}", key, r#type);
if r#type == KeyType::Press {
let mut inner = PAD.exclusive_access();
let a = inner.as_ref().unwrap();
match key.to_char() {
Ok(mut k) => {
if k == '\r' {
a.repaint(k.to_string() + "\n")
} else {
a.repaint(k.to_string())
}
},
Err(_) => {},
}
}
}
virtio_input_decoder::DecodeType::Mouse(mouse) => println!("{:?}", mouse),
}
}
}

View file

@ -1,6 +1,9 @@
pub mod block;
pub mod chardev;
pub mod plic;
pub mod gpu;
pub mod input;
pub use block::BLOCK_DEVICE;
pub use chardev::UART;
pub use gpu::*;
pub use input::*;