mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 09:26:26 +04:00
feat: simple drawing board GUI
This commit is contained in:
parent
2ca2132df2
commit
20d4f5fe08
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@ os/src/link_app.S
|
|||||||
os/src/linker.ld
|
os/src/linker.ld
|
||||||
os/last-*
|
os/last-*
|
||||||
os/.gdb_history
|
os/.gdb_history
|
||||||
|
os/virt.out
|
||||||
tools/
|
tools/
|
||||||
pushall.sh
|
pushall.sh
|
||||||
.vscode/*.log
|
.vscode/*.log
|
@ -18,6 +18,8 @@ easy-fs = { path = "../easy-fs" }
|
|||||||
virtio-input-decoder = "0.1.4"
|
virtio-input-decoder = "0.1.4"
|
||||||
embedded-graphics = "0.7.1"
|
embedded-graphics = "0.7.1"
|
||||||
tinybmp = "0.3.1"
|
tinybmp = "0.3.1"
|
||||||
|
embedded-term = { git = "https://github.com/rcore-os/embedded-term" }
|
||||||
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
29
os/Makefile
29
os/Makefile
@ -12,6 +12,12 @@ BOARD := qemu
|
|||||||
SBI ?= rustsbi
|
SBI ?= rustsbi
|
||||||
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
|
BOOTLOADER := ../bootloader/$(SBI)-$(BOARD).bin
|
||||||
|
|
||||||
|
# GUI
|
||||||
|
GUI ?= off
|
||||||
|
ifeq ($(GUI), off)
|
||||||
|
GUI_OPTION := -display none
|
||||||
|
endif
|
||||||
|
|
||||||
# Building mode argument
|
# Building mode argument
|
||||||
ifeq ($(MODE), release)
|
ifeq ($(MODE), release)
|
||||||
MODE_ARG := --release
|
MODE_ARG := --release
|
||||||
@ -67,27 +73,12 @@ disasm-vim: kernel
|
|||||||
|
|
||||||
run: run-inner
|
run: run-inner
|
||||||
|
|
||||||
gui: build
|
|
||||||
ifeq ($(BOARD),qemu)
|
|
||||||
@qemu-system-riscv64 \
|
|
||||||
-M 128m \
|
|
||||||
-machine virt \
|
|
||||||
-bios $(BOOTLOADER) \
|
|
||||||
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) \
|
|
||||||
-drive file=$(FS_IMG),if=none,format=raw,id=x0 \
|
|
||||||
-device virtio-blk-device,drive=x0 \
|
|
||||||
-device virtio-gpu-device \
|
|
||||||
-device virtio-keyboard-device \
|
|
||||||
-device virtio-mouse-device \
|
|
||||||
-serial stdio
|
|
||||||
endif
|
|
||||||
|
|
||||||
run-inner: build
|
run-inner: build
|
||||||
@qemu-system-riscv64 \
|
@qemu-system-riscv64 \
|
||||||
-M 128m \
|
-M 128m \
|
||||||
-machine virt \
|
-machine virt \
|
||||||
-bios $(BOOTLOADER) \
|
-bios $(BOOTLOADER) \
|
||||||
-display none \
|
$(GUI_OPTION) \
|
||||||
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) \
|
-device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) \
|
||||||
-drive file=$(FS_IMG),if=none,format=raw,id=x0 \
|
-drive file=$(FS_IMG),if=none,format=raw,id=x0 \
|
||||||
-device virtio-blk-device,drive=x0 \
|
-device virtio-blk-device,drive=x0 \
|
||||||
@ -96,6 +87,10 @@ run-inner: build
|
|||||||
-device virtio-mouse-device \
|
-device virtio-mouse-device \
|
||||||
-serial stdio
|
-serial stdio
|
||||||
|
|
||||||
|
fdt:
|
||||||
|
@qemu-system-riscv64 -M 128m -machine virt,dumpdtb=virt.out
|
||||||
|
fdtdump virt.out
|
||||||
|
|
||||||
debug: build
|
debug: build
|
||||||
@tmux new-session -d \
|
@tmux new-session -d \
|
||||||
"qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S" && \
|
"qemu-system-riscv64 -machine virt -nographic -bios $(BOOTLOADER) -device loader,file=$(KERNEL_BIN),addr=$(KERNEL_ENTRY_PA) -s -S" && \
|
||||||
@ -109,4 +104,4 @@ gdbserver: build
|
|||||||
gdbclient:
|
gdbclient:
|
||||||
@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'
|
@riscv64-unknown-elf-gdb -ex 'file $(KERNEL_ELF)' -ex 'set arch riscv:rv64' -ex 'target remote localhost:1234'
|
||||||
|
|
||||||
.PHONY: build env kernel clean disasm disasm-vim run-inner fs-img gdbserver gdbclient
|
.PHONY: build env kernel clean disasm disasm-vim run-inner fs-img gdbserver gdbclient fdt
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
qemu-system-riscv64 -M 128m -machine virt,dumpdtb=virt.out \
|
|
||||||
-bios ../bootloader/rustsbi-qemu.bin \
|
|
||||||
-device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 \
|
|
||||||
-drive file=../user/target/riscv64gc-unknown-none-elf/release/fs.img,if=none,format=raw,id=x0 \
|
|
||||||
-device virtio-blk-device,drive=x0 \
|
|
||||||
-device virtio-gpu-device \
|
|
||||||
-device virtio-keyboard-device \
|
|
||||||
-device virtio-mouse-device \
|
|
||||||
-serial stdio
|
|
||||||
|
|
||||||
fdtdump virt.out
|
|
@ -1,10 +0,0 @@
|
|||||||
qemu-system-riscv64 -M 128m -machine virt \
|
|
||||||
-bios ../bootloader/rustsbi-qemu.bin \
|
|
||||||
-display none \
|
|
||||||
-device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 \
|
|
||||||
-drive file=../user/target/riscv64gc-unknown-none-elf/release/fs.img,if=none,format=raw,id=x0 \
|
|
||||||
-device virtio-blk-device,drive=x0 \
|
|
||||||
-device virtio-gpu-device \
|
|
||||||
-device virtio-keyboard-device \
|
|
||||||
-device virtio-mouse-device \
|
|
||||||
-serial stdio
|
|
@ -1,9 +0,0 @@
|
|||||||
qemu-system-riscv64 -M 128m -machine virt \
|
|
||||||
-bios ../bootloader/rustsbi-qemu.bin \
|
|
||||||
-device loader,file=target/riscv64gc-unknown-none-elf/release/os.bin,addr=0x80200000 \
|
|
||||||
-drive file=../user/target/riscv64gc-unknown-none-elf/release/fs.img,if=none,format=raw,id=x0 \
|
|
||||||
-device virtio-blk-device,drive=x0 \
|
|
||||||
-device virtio-gpu-device \
|
|
||||||
-device virtio-keyboard-device \
|
|
||||||
-device virtio-mouse-device \
|
|
||||||
-serial stdio
|
|
@ -14,6 +14,7 @@ pub const VIRT_PLIC: usize = 0xC00_0000;
|
|||||||
pub const VIRT_UART: usize = 0x1000_0000;
|
pub const VIRT_UART: usize = 0x1000_0000;
|
||||||
|
|
||||||
pub const VIRTGPU_XRES: u32 = 1280;
|
pub const VIRTGPU_XRES: u32 = 1280;
|
||||||
|
#[allow(unused)]
|
||||||
pub const VIRTGPU_YRES: u32 = 800;
|
pub const VIRTGPU_YRES: u32 = 800;
|
||||||
|
|
||||||
use crate::drivers::block::BLOCK_DEVICE;
|
use crate::drivers::block::BLOCK_DEVICE;
|
||||||
@ -30,7 +31,7 @@ pub fn device_init() {
|
|||||||
plic.set_threshold(hart_id, supervisor, 0);
|
plic.set_threshold(hart_id, supervisor, 0);
|
||||||
plic.set_threshold(hart_id, machine, 1);
|
plic.set_threshold(hart_id, machine, 1);
|
||||||
//irq nums: 5 keyboard, 6 mouse, 8 block, 10 uart
|
//irq nums: 5 keyboard, 6 mouse, 8 block, 10 uart
|
||||||
for intr_src_id in [5usize, 6, 8 , 10] {
|
for intr_src_id in [5usize, 6, 8, 10] {
|
||||||
plic.enable(hart_id, supervisor, intr_src_id);
|
plic.enable(hart_id, supervisor, intr_src_id);
|
||||||
plic.set_priority(intr_src_id, 1);
|
plic.set_priority(intr_src_id, 1);
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use super::BlockDevice;
|
use super::BlockDevice;
|
||||||
|
use crate::drivers::bus::virtio::VirtioHal;
|
||||||
use crate::sync::{Condvar, UPIntrFreeCell};
|
use crate::sync::{Condvar, UPIntrFreeCell};
|
||||||
use crate::task::schedule;
|
use crate::task::schedule;
|
||||||
use crate::DEV_NON_BLOCKING_ACCESS;
|
use crate::DEV_NON_BLOCKING_ACCESS;
|
||||||
use alloc::collections::BTreeMap;
|
use alloc::collections::BTreeMap;
|
||||||
use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader};
|
use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader};
|
||||||
use crate::drivers::bus::virtio::VirtioHal;
|
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
const VIRTIO0: usize = 0x10008000;
|
const VIRTIO0: usize = 0x10008000;
|
||||||
@ -69,7 +69,9 @@ impl BlockDevice for VirtIOBlock {
|
|||||||
impl VirtIOBlock {
|
impl VirtIOBlock {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let virtio_blk = unsafe {
|
let virtio_blk = unsafe {
|
||||||
UPIntrFreeCell::new(VirtIOBlk::<VirtioHal>::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap())
|
UPIntrFreeCell::new(
|
||||||
|
VirtIOBlk::<VirtioHal>::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let mut condvars = BTreeMap::new();
|
let mut condvars = BTreeMap::new();
|
||||||
let channels = virtio_blk.exclusive_access().virt_queue_size();
|
let channels = virtio_blk.exclusive_access().virt_queue_size();
|
||||||
@ -83,4 +85,3 @@ impl VirtIOBlock {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use alloc::vec::Vec;
|
|
||||||
use crate::mm::{
|
use crate::mm::{
|
||||||
frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum,
|
frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum,
|
||||||
StepByOne, VirtAddr,
|
StepByOne, VirtAddr,
|
||||||
};
|
};
|
||||||
use crate::sync::UPIntrFreeCell;
|
use crate::sync::UPIntrFreeCell;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
use virtio_drivers::Hal;
|
use virtio_drivers::Hal;
|
||||||
|
|
||||||
|
@ -1,30 +1,31 @@
|
|||||||
|
use crate::drivers::bus::virtio::VirtioHal;
|
||||||
use crate::sync::UPIntrFreeCell;
|
use crate::sync::UPIntrFreeCell;
|
||||||
use alloc::{sync::Arc, vec::Vec};
|
use alloc::{sync::Arc, vec::Vec};
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
use embedded_graphics::pixelcolor::Rgb888;
|
use embedded_graphics::pixelcolor::Rgb888;
|
||||||
use tinybmp::Bmp;
|
use tinybmp::Bmp;
|
||||||
use virtio_drivers::{VirtIOGpu, VirtIOHeader};
|
use virtio_drivers::{VirtIOGpu, VirtIOHeader};
|
||||||
use crate::drivers::bus::virtio::VirtioHal;
|
|
||||||
const VIRTIO7: usize = 0x10007000;
|
const VIRTIO7: usize = 0x10007000;
|
||||||
pub trait GPUDevice: Send + Sync + Any {
|
pub trait GpuDevice: Send + Sync + Any {
|
||||||
fn update_cursor(&self);
|
fn update_cursor(&self);
|
||||||
fn getfreambuffer(&self) -> &mut [u8];
|
fn get_framebuffer(&self) -> &mut [u8];
|
||||||
fn flush(&self);
|
fn flush(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
lazy_static::lazy_static!(
|
||||||
pub static ref GPU_DEVICE: Arc<dyn GPUDevice> = Arc::new(VirtIOGPU::new());
|
pub static ref GPU_DEVICE: Arc<dyn GpuDevice> = Arc::new(VirtIOGpuWrapper::new());
|
||||||
);
|
);
|
||||||
|
|
||||||
pub struct VirtIOGPU {
|
pub struct VirtIOGpuWrapper {
|
||||||
gpu: UPIntrFreeCell<VirtIOGpu<'static, VirtioHal>>,
|
gpu: UPIntrFreeCell<VirtIOGpu<'static, VirtioHal>>,
|
||||||
fb: &'static [u8],
|
fb: &'static [u8],
|
||||||
}
|
}
|
||||||
static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
|
static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
|
||||||
impl VirtIOGPU {
|
impl VirtIOGpuWrapper {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut virtio = VirtIOGpu::<VirtioHal>::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
|
let mut virtio =
|
||||||
|
VirtIOGpu::<VirtioHal>::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
|
||||||
|
|
||||||
let fbuffer = virtio.setup_framebuffer().unwrap();
|
let fbuffer = virtio.setup_framebuffer().unwrap();
|
||||||
let len = fbuffer.len();
|
let len = fbuffer.len();
|
||||||
@ -53,11 +54,11 @@ impl VirtIOGPU {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPUDevice for VirtIOGPU {
|
impl GpuDevice for VirtIOGpuWrapper {
|
||||||
fn flush(&self) {
|
fn flush(&self) {
|
||||||
self.gpu.exclusive_access().flush().unwrap();
|
self.gpu.exclusive_access().flush().unwrap();
|
||||||
}
|
}
|
||||||
fn getfreambuffer(&self) -> &mut [u8] {
|
fn get_framebuffer(&self) -> &mut [u8] {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = self.fb.as_ptr() as *const _ as *mut u8;
|
let ptr = self.fb.as_ptr() as *const _ as *mut u8;
|
||||||
core::slice::from_raw_parts_mut(ptr, self.fb.len())
|
core::slice::from_raw_parts_mut(ptr, self.fb.len())
|
||||||
|
@ -1,74 +1,75 @@
|
|||||||
use crate::{
|
|
||||||
gui::{Button, Component},
|
|
||||||
sync::UPIntrFreeCell,
|
|
||||||
syscall::PAD,
|
|
||||||
};
|
|
||||||
use alloc::{string::ToString, sync::Arc};
|
|
||||||
use core::any::Any;
|
|
||||||
use embedded_graphics::{
|
|
||||||
prelude::{Point, Size},
|
|
||||||
text::Text,
|
|
||||||
};
|
|
||||||
use virtio_drivers::{VirtIOHeader, VirtIOInput};
|
|
||||||
use crate::drivers::bus::virtio::VirtioHal;
|
use crate::drivers::bus::virtio::VirtioHal;
|
||||||
|
use crate::{
|
||||||
|
gui::{move_rect, reset},
|
||||||
|
sync::UPIntrFreeCell,
|
||||||
|
};
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use core::any::Any;
|
||||||
|
use virtio_drivers::{VirtIOHeader, VirtIOInput};
|
||||||
use virtio_input_decoder::{Decoder, Key, KeyType};
|
use virtio_input_decoder::{Decoder, Key, KeyType};
|
||||||
|
|
||||||
use super::GPU_DEVICE;
|
|
||||||
|
|
||||||
const VIRTIO5: usize = 0x10005000;
|
const VIRTIO5: usize = 0x10005000;
|
||||||
const VIRTIO6: usize = 0x10006000;
|
const VIRTIO6: usize = 0x10006000;
|
||||||
|
|
||||||
struct VirtIOINPUT(UPIntrFreeCell<VirtIOInput<'static, VirtioHal>>);
|
struct VirtIOInputWrapper(UPIntrFreeCell<VirtIOInput<'static, VirtioHal>>);
|
||||||
|
|
||||||
pub trait INPUTDevice: Send + Sync + Any {
|
pub trait InputDevice: Send + Sync + Any {
|
||||||
fn handle_irq(&self);
|
fn handle_irq(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
lazy_static::lazy_static!(
|
||||||
pub static ref KEYBOARD_DEVICE: Arc<dyn INPUTDevice> = Arc::new(VirtIOINPUT::new(VIRTIO5));
|
pub static ref KEYBOARD_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO5));
|
||||||
pub static ref MOUSE_DEVICE: Arc<dyn INPUTDevice> = Arc::new(VirtIOINPUT::new(VIRTIO6));
|
pub static ref MOUSE_DEVICE: Arc<dyn InputDevice> = Arc::new(VirtIOInputWrapper::new(VIRTIO6));
|
||||||
);
|
);
|
||||||
|
|
||||||
impl VirtIOINPUT {
|
impl VirtIOInputWrapper {
|
||||||
pub fn new(addr: usize) -> Self {
|
pub fn new(addr: usize) -> Self {
|
||||||
Self(unsafe {
|
Self(unsafe {
|
||||||
UPIntrFreeCell::new(VirtIOInput::<VirtioHal>::new(&mut *(addr as *mut VirtIOHeader)).unwrap())
|
UPIntrFreeCell::new(
|
||||||
|
VirtIOInput::<VirtioHal>::new(&mut *(addr as *mut VirtIOHeader)).unwrap(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl INPUTDevice for VirtIOINPUT {
|
impl InputDevice for VirtIOInputWrapper {
|
||||||
fn handle_irq(&self) {
|
fn handle_irq(&self) {
|
||||||
let mut input = self.0.exclusive_access();
|
let mut input = self.0.exclusive_access();
|
||||||
input.ack_interrupt();
|
input.ack_interrupt();
|
||||||
let event = input.pop_pending_event().unwrap();
|
while let Some(event) = input.pop_pending_event() {
|
||||||
let dtype = match Decoder::decode(
|
let dtype = match Decoder::decode(
|
||||||
event.event_type as usize,
|
event.event_type as usize,
|
||||||
event.code as usize,
|
event.code as usize,
|
||||||
event.value as usize,
|
event.value as usize,
|
||||||
) {
|
) {
|
||||||
Ok(dtype) => dtype,
|
Ok(dtype) => dtype,
|
||||||
Err(_) => return,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
match dtype {
|
match dtype {
|
||||||
virtio_input_decoder::DecodeType::Key(key, r#type) => {
|
virtio_input_decoder::DecodeType::Key(key, r#type) => {
|
||||||
println!("{:?} {:?}", key, r#type);
|
if r#type == KeyType::Press {
|
||||||
if r#type == KeyType::Press {
|
match key {
|
||||||
let mut inner = PAD.exclusive_access();
|
Key::C | Key::MouseLeft => {
|
||||||
let a = inner.as_ref().unwrap();
|
reset();
|
||||||
match key.to_char() {
|
|
||||||
Ok(mut k) => {
|
|
||||||
if k == '\r' {
|
|
||||||
a.repaint(k.to_string() + "\n")
|
|
||||||
} else {
|
|
||||||
a.repaint(k.to_string())
|
|
||||||
}
|
}
|
||||||
|
Key::W => {
|
||||||
|
move_rect(0, -10);
|
||||||
|
}
|
||||||
|
Key::S => {
|
||||||
|
move_rect(0, 10);
|
||||||
|
}
|
||||||
|
Key::A => {
|
||||||
|
move_rect(-10, 0);
|
||||||
|
}
|
||||||
|
Key::D => {
|
||||||
|
move_rect(10, 0);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
virtio_input_decoder::DecodeType::Mouse(mouse) => println!("{:?}", mouse),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
pub mod block;
|
pub mod block;
|
||||||
|
pub mod bus;
|
||||||
pub mod chardev;
|
pub mod chardev;
|
||||||
pub mod gpu;
|
pub mod gpu;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod bus;
|
|
||||||
pub mod plic;
|
pub mod plic;
|
||||||
|
|
||||||
pub use block::BLOCK_DEVICE;
|
pub use block::BLOCK_DEVICE;
|
||||||
|
pub use bus::*;
|
||||||
pub use chardev::UART;
|
pub use chardev::UART;
|
||||||
pub use gpu::*;
|
pub use gpu::*;
|
||||||
pub use input::*;
|
pub use input::*;
|
||||||
pub use bus::*;
|
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
use alloc::{string::String, sync::Arc};
|
|
||||||
use embedded_graphics::{
|
|
||||||
mono_font::{
|
|
||||||
ascii::{FONT_10X20, FONT_6X10},
|
|
||||||
MonoTextStyle,
|
|
||||||
},
|
|
||||||
pixelcolor::Rgb888,
|
|
||||||
prelude::{Dimensions, Point, Primitive, RgbColor, Size},
|
|
||||||
primitives::{PrimitiveStyle, Rectangle},
|
|
||||||
text::{Alignment, Text},
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{drivers::GPU_DEVICE, sync::UPIntrFreeCell};
|
|
||||||
|
|
||||||
use super::{Component, Graphics};
|
|
||||||
|
|
||||||
pub struct Button {
|
|
||||||
inner: UPIntrFreeCell<ButtonInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ButtonInner {
|
|
||||||
graphic: Graphics,
|
|
||||||
text: String,
|
|
||||||
parent: Option<Arc<dyn Component>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Button {
|
|
||||||
pub fn new(size: Size, point: Point, parent: Option<Arc<dyn Component>>, text: String) -> Self {
|
|
||||||
let point = match &parent {
|
|
||||||
Some(p) => {
|
|
||||||
let (_, p) = p.bound();
|
|
||||||
Point::new(p.x + point.x, p.y + point.y)
|
|
||||||
}
|
|
||||||
None => point,
|
|
||||||
};
|
|
||||||
Self {
|
|
||||||
inner: unsafe {
|
|
||||||
UPIntrFreeCell::new(ButtonInner {
|
|
||||||
graphic: Graphics {
|
|
||||||
size,
|
|
||||||
point,
|
|
||||||
drv: GPU_DEVICE.clone(),
|
|
||||||
},
|
|
||||||
text,
|
|
||||||
parent,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for Button {
|
|
||||||
fn paint(&self) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let text = inner.text.clone();
|
|
||||||
Text::with_alignment(
|
|
||||||
text.as_str(),
|
|
||||||
inner.graphic.bounding_box().center(),
|
|
||||||
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
|
|
||||||
Alignment::Center,
|
|
||||||
)
|
|
||||||
.draw(&mut inner.graphic);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add(&self, comp: alloc::sync::Arc<dyn Component>) {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bound(
|
|
||||||
&self,
|
|
||||||
) -> (
|
|
||||||
embedded_graphics::prelude::Size,
|
|
||||||
embedded_graphics::prelude::Point,
|
|
||||||
) {
|
|
||||||
let inner = self.inner.exclusive_access();
|
|
||||||
(inner.graphic.size, inner.graphic.point)
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,14 +5,14 @@ use embedded_graphics::{
|
|||||||
prelude::{OriginDimensions, Point, RgbColor, Size},
|
prelude::{OriginDimensions, Point, RgbColor, Size},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::drivers::{GPUDevice, GPU_DEVICE,};
|
use crate::board::VIRTGPU_XRES;
|
||||||
use crate::board::{VIRTGPU_XRES, VIRTGPU_YRES};
|
use crate::drivers::{GpuDevice, GPU_DEVICE};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Graphics {
|
pub struct Graphics {
|
||||||
pub size: Size,
|
pub size: Size,
|
||||||
pub point: Point,
|
pub point: Point,
|
||||||
pub drv: Arc<dyn GPUDevice>,
|
pub drv: Arc<dyn GpuDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Graphics {
|
impl Graphics {
|
||||||
@ -23,6 +23,10 @@ impl Graphics {
|
|||||||
drv: GPU_DEVICE.clone(),
|
drv: GPU_DEVICE.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn reset(&self) {
|
||||||
|
let fb = self.drv.get_framebuffer();
|
||||||
|
fb.fill(0u8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OriginDimensions for Graphics {
|
impl OriginDimensions for Graphics {
|
||||||
@ -40,10 +44,12 @@ impl DrawTarget for Graphics {
|
|||||||
where
|
where
|
||||||
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
|
I: IntoIterator<Item = embedded_graphics::Pixel<Self::Color>>,
|
||||||
{
|
{
|
||||||
let fb = self.drv.getfreambuffer();
|
let fb = self.drv.get_framebuffer();
|
||||||
|
|
||||||
pixels.into_iter().for_each(|px| {
|
pixels.into_iter().for_each(|px| {
|
||||||
let idx = ((self.point.y + px.0.y) * VIRTGPU_XRES as i32 + self.point.x + px.0.x) as usize * 4;
|
let idx = ((self.point.y + px.0.y) * VIRTGPU_XRES as i32 + self.point.x + px.0.x)
|
||||||
|
as usize
|
||||||
|
* 4;
|
||||||
if idx + 2 >= fb.len() {
|
if idx + 2 >= fb.len() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
|
||||||
use embedded_graphics::{
|
|
||||||
image::Image,
|
|
||||||
mono_font::{ascii::FONT_10X20, iso_8859_13::FONT_6X12, MonoTextStyle},
|
|
||||||
pixelcolor::Rgb888,
|
|
||||||
prelude::{Point, RgbColor, Size},
|
|
||||||
text::Text,
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
use tinybmp::Bmp;
|
|
||||||
|
|
||||||
use crate::{drivers::GPU_DEVICE, sync::UPIntrFreeCell};
|
|
||||||
use crate::board::{VIRTGPU_XRES, VIRTGPU_YRES};
|
|
||||||
use super::{Component, Graphics, ImageComp};
|
|
||||||
|
|
||||||
static FILEICON: &[u8] = include_bytes!("../assert/file.bmp");
|
|
||||||
|
|
||||||
pub struct IconController {
|
|
||||||
inner: UPIntrFreeCell<IconControllerInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct IconControllerInner {
|
|
||||||
files: Vec<String>,
|
|
||||||
graphic: Graphics,
|
|
||||||
parent: Option<Arc<dyn Component>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IconController {
|
|
||||||
pub fn new(files: Vec<String>, parent: Option<Arc<dyn Component>>) -> Self {
|
|
||||||
IconController {
|
|
||||||
inner: unsafe {
|
|
||||||
UPIntrFreeCell::new(IconControllerInner {
|
|
||||||
files,
|
|
||||||
graphic: Graphics {
|
|
||||||
size: Size::new(VIRTGPU_XRES, VIRTGPU_YRES),
|
|
||||||
point: Point::new(0, 0),
|
|
||||||
drv: GPU_DEVICE.clone(),
|
|
||||||
},
|
|
||||||
parent,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for IconController {
|
|
||||||
fn paint(&self) {
|
|
||||||
println!("demo");
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let mut x = 10;
|
|
||||||
let mut y = 10;
|
|
||||||
let v = inner.files.clone();
|
|
||||||
for file in v {
|
|
||||||
println!("file");
|
|
||||||
let bmp = Bmp::<Rgb888>::from_slice(FILEICON).unwrap();
|
|
||||||
Image::new(&bmp, Point::new(x, y)).draw(&mut inner.graphic);
|
|
||||||
let text = Text::new(
|
|
||||||
file.as_str(),
|
|
||||||
Point::new(x + 20, y + 80),
|
|
||||||
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
|
|
||||||
);
|
|
||||||
text.draw(&mut inner.graphic);
|
|
||||||
if y >= 600 {
|
|
||||||
x = x + 70;
|
|
||||||
y = 10;
|
|
||||||
} else {
|
|
||||||
y = y + 90;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add(&self, comp: Arc<dyn Component>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bound(&self) -> (Size, Point) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,80 +0,0 @@
|
|||||||
use alloc::{sync::Arc, vec::Vec};
|
|
||||||
use embedded_graphics::{
|
|
||||||
image::Image,
|
|
||||||
pixelcolor::Rgb888,
|
|
||||||
prelude::{Point, Size},
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
use tinybmp::Bmp;
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
drivers::{BLOCK_DEVICE, GPU_DEVICE},
|
|
||||||
sync::UPIntrFreeCell,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{Component, Graphics};
|
|
||||||
|
|
||||||
pub struct ImageComp {
|
|
||||||
inner: UPIntrFreeCell<ImageInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ImageInner {
|
|
||||||
image: &'static [u8],
|
|
||||||
graphic: Graphics,
|
|
||||||
parent: Option<Arc<dyn Component>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ImageComp {
|
|
||||||
pub fn new(
|
|
||||||
size: Size,
|
|
||||||
point: Point,
|
|
||||||
v: &'static [u8],
|
|
||||||
parent: Option<Arc<dyn Component>>,
|
|
||||||
) -> Self {
|
|
||||||
unsafe {
|
|
||||||
ImageComp {
|
|
||||||
inner: UPIntrFreeCell::new(ImageInner {
|
|
||||||
parent,
|
|
||||||
image: v,
|
|
||||||
graphic: Graphics {
|
|
||||||
size,
|
|
||||||
point,
|
|
||||||
drv: GPU_DEVICE.clone(),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for ImageComp {
|
|
||||||
fn paint(&self) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let b = unsafe {
|
|
||||||
let len = inner.image.len();
|
|
||||||
let ptr = inner.image.as_ptr() as *const u8;
|
|
||||||
core::slice::from_raw_parts(ptr, len)
|
|
||||||
};
|
|
||||||
let bmp = Bmp::<Rgb888>::from_slice(b).unwrap();
|
|
||||||
let point = match &inner.parent {
|
|
||||||
Some(parent) => {
|
|
||||||
let (_, point) = parent.bound();
|
|
||||||
Point::new(
|
|
||||||
point.x + inner.graphic.point.x,
|
|
||||||
point.y + inner.graphic.point.y,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
None => inner.graphic.point,
|
|
||||||
};
|
|
||||||
Image::new(&bmp, point).draw(&mut inner.graphic);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add(&self, comp: alloc::sync::Arc<dyn Component>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bound(&self) -> (Size, Point) {
|
|
||||||
let inner = self.inner.exclusive_access();
|
|
||||||
(inner.graphic.size, inner.graphic.point)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +1,5 @@
|
|||||||
mod button;
|
|
||||||
mod graphic;
|
mod graphic;
|
||||||
mod icon;
|
mod paint;
|
||||||
mod image;
|
|
||||||
mod panel;
|
|
||||||
mod terminal;
|
|
||||||
|
|
||||||
use alloc::sync::Arc;
|
use graphic::Graphics;
|
||||||
pub use button::*;
|
pub use paint::{init_paint, move_rect, reset};
|
||||||
use core::any::Any;
|
|
||||||
use embedded_graphics::prelude::{Point, Size};
|
|
||||||
pub use graphic::*;
|
|
||||||
pub use icon::*;
|
|
||||||
pub use image::*;
|
|
||||||
pub use panel::*;
|
|
||||||
pub use terminal::*;
|
|
||||||
|
|
||||||
pub trait Component: Send + Sync + Any {
|
|
||||||
fn paint(&self);
|
|
||||||
fn add(&self, comp: Arc<dyn Component>);
|
|
||||||
fn bound(&self) -> (Size, Point);
|
|
||||||
}
|
|
||||||
|
62
os/src/gui/paint.rs
Normal file
62
os/src/gui/paint.rs
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use super::Graphics;
|
||||||
|
use crate::sync::UPIntrFreeCell;
|
||||||
|
use embedded_graphics::pixelcolor::Rgb888;
|
||||||
|
use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size};
|
||||||
|
use embedded_graphics::primitives::Primitive;
|
||||||
|
use embedded_graphics::primitives::{PrimitiveStyle, Rectangle};
|
||||||
|
use lazy_static::*;
|
||||||
|
|
||||||
|
const INIT_X: i32 = 640;
|
||||||
|
const INIT_Y: i32 = 400;
|
||||||
|
const RECT_SIZE: u32 = 40;
|
||||||
|
|
||||||
|
pub struct DrawingBoard {
|
||||||
|
graphics: Graphics,
|
||||||
|
latest_pos: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawingBoard {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
graphics: Graphics::new(Size::new(1280, 800), Point::new(0, 0)),
|
||||||
|
latest_pos: Point::new(INIT_X, INIT_Y),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn paint(&mut self) {
|
||||||
|
Rectangle::with_center(self.latest_pos, Size::new(RECT_SIZE, RECT_SIZE))
|
||||||
|
.into_styled(PrimitiveStyle::with_stroke(Rgb888::WHITE, 1))
|
||||||
|
.draw(&mut self.graphics)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
pub fn move_rect(&mut self, dx: i32, dy: i32) {
|
||||||
|
self.latest_pos.x += dx;
|
||||||
|
self.latest_pos.y += dy;
|
||||||
|
self.paint();
|
||||||
|
}
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.latest_pos = Point::new(INIT_X, INIT_Y);
|
||||||
|
self.graphics.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref DRAWING_BOARD: UPIntrFreeCell<DrawingBoard> = unsafe { UPIntrFreeCell::new(DrawingBoard::new()) };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_paint() {
|
||||||
|
DRAWING_BOARD.exclusive_session(|ripple| {
|
||||||
|
ripple.paint();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn move_rect(dx: i32, dy: i32) {
|
||||||
|
DRAWING_BOARD.exclusive_session(|ripple| {
|
||||||
|
ripple.move_rect(dx, dy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset() {
|
||||||
|
DRAWING_BOARD.exclusive_session(|ripple| {
|
||||||
|
ripple.reset();
|
||||||
|
});
|
||||||
|
}
|
@ -1,66 +0,0 @@
|
|||||||
use alloc::{collections::VecDeque, rc::Weak, sync::Arc};
|
|
||||||
use embedded_graphics::{
|
|
||||||
pixelcolor::Rgb888,
|
|
||||||
prelude::{Point, Primitive, RgbColor, Size},
|
|
||||||
primitives::{PrimitiveStyle, Rectangle},
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{drivers::GPU_DEVICE, sync::UPIntrFreeCell};
|
|
||||||
|
|
||||||
use super::{Component, Graphics};
|
|
||||||
|
|
||||||
pub struct Panel {
|
|
||||||
inner: UPIntrFreeCell<PanelInner>,
|
|
||||||
}
|
|
||||||
struct PanelInner {
|
|
||||||
graphic: Graphics,
|
|
||||||
comps: VecDeque<Arc<dyn Component>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Panel {
|
|
||||||
pub fn new(size: Size, point: Point) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: unsafe {
|
|
||||||
UPIntrFreeCell::new(PanelInner {
|
|
||||||
graphic: Graphics {
|
|
||||||
size,
|
|
||||||
point,
|
|
||||||
drv: GPU_DEVICE.clone(),
|
|
||||||
},
|
|
||||||
comps: VecDeque::new(),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for Panel {
|
|
||||||
fn paint(&self) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
|
|
||||||
Rectangle::new(Point::new(0, 0), inner.graphic.size)
|
|
||||||
.into_styled(PrimitiveStyle::with_fill(Rgb888::WHITE))
|
|
||||||
.draw(&mut inner.graphic)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let len = inner.comps.len();
|
|
||||||
drop(inner);
|
|
||||||
for i in 0..len {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let comp = Arc::downgrade(&inner.comps[i]);
|
|
||||||
drop(inner);
|
|
||||||
comp.upgrade().unwrap().paint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add(&self, comp: alloc::sync::Arc<dyn Component>) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
inner.comps.push_back(comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bound(&self) -> (Size, Point) {
|
|
||||||
let inner = self.inner.exclusive_access();
|
|
||||||
(inner.graphic.size, inner.graphic.point)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
use alloc::{
|
|
||||||
collections::VecDeque,
|
|
||||||
string::{String, ToString},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
use embedded_graphics::{
|
|
||||||
mono_font::{ascii::FONT_10X20, MonoTextStyle},
|
|
||||||
pixelcolor::Rgb888,
|
|
||||||
prelude::{Dimensions, Point, Primitive, RgbColor, Size},
|
|
||||||
primitives::{PrimitiveStyle, Rectangle},
|
|
||||||
text::{Alignment, Text},
|
|
||||||
Drawable,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{drivers::GPU_DEVICE, sync::UPIntrFreeCell};
|
|
||||||
|
|
||||||
use super::{button::Button, Component, Graphics, Panel};
|
|
||||||
|
|
||||||
pub struct Terminal {
|
|
||||||
inner: UPIntrFreeCell<TerminalInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TerminalInner {
|
|
||||||
pub text: String,
|
|
||||||
titel: Option<String>,
|
|
||||||
graphic: Graphics,
|
|
||||||
comps: VecDeque<Arc<dyn Component>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Terminal {
|
|
||||||
pub fn new(
|
|
||||||
size: Size,
|
|
||||||
point: Point,
|
|
||||||
parent: Option<Arc<dyn Component>>,
|
|
||||||
titel: Option<String>,
|
|
||||||
text: String,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: unsafe {
|
|
||||||
UPIntrFreeCell::new(TerminalInner {
|
|
||||||
text,
|
|
||||||
titel,
|
|
||||||
graphic: Graphics {
|
|
||||||
size,
|
|
||||||
point,
|
|
||||||
drv: GPU_DEVICE.clone(),
|
|
||||||
},
|
|
||||||
comps: VecDeque::new(),
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn repaint(&self, text: String) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
inner.text += text.as_str();
|
|
||||||
Text::with_alignment(
|
|
||||||
inner.text.clone().as_str(),
|
|
||||||
Point::new(20, 50),
|
|
||||||
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
|
|
||||||
Alignment::Left,
|
|
||||||
)
|
|
||||||
.draw(&mut inner.graphic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for Terminal {
|
|
||||||
fn paint(&self) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let len = inner.comps.len();
|
|
||||||
drop(inner);
|
|
||||||
for i in 0..len {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let comp = Arc::downgrade(&inner.comps[i]);
|
|
||||||
drop(inner);
|
|
||||||
comp.upgrade().unwrap().paint();
|
|
||||||
}
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
let titel = inner.titel.get_or_insert("No Titel".to_string()).clone();
|
|
||||||
let text = Text::new(
|
|
||||||
titel.as_str(),
|
|
||||||
Point::new(20, 20),
|
|
||||||
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
|
|
||||||
);
|
|
||||||
text.draw(&mut inner.graphic);
|
|
||||||
|
|
||||||
Text::with_alignment(
|
|
||||||
inner.text.clone().as_str(),
|
|
||||||
Point::new(20, 50),
|
|
||||||
MonoTextStyle::new(&FONT_10X20, Rgb888::BLACK),
|
|
||||||
Alignment::Left,
|
|
||||||
)
|
|
||||||
.draw(&mut inner.graphic);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add(&self, comp: Arc<dyn Component>) {
|
|
||||||
let mut inner = self.inner.exclusive_access();
|
|
||||||
inner.comps.push_back(comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bound(&self) -> (Size, Point) {
|
|
||||||
let inner = self.inner.exclusive_access();
|
|
||||||
(inner.graphic.size, inner.graphic.point)
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,7 +28,7 @@ mod task;
|
|||||||
mod timer;
|
mod timer;
|
||||||
mod trap;
|
mod trap;
|
||||||
|
|
||||||
// use syscall::create_desktop; //for test
|
//use syscall::create_desktop; //for test
|
||||||
|
|
||||||
core::arch::global_asm!(include_str!("entry.asm"));
|
core::arch::global_asm!(include_str!("entry.asm"));
|
||||||
|
|
||||||
@ -56,18 +56,18 @@ pub fn rust_main() -> ! {
|
|||||||
clear_bss();
|
clear_bss();
|
||||||
mm::init();
|
mm::init();
|
||||||
println!("KERN: init gpu");
|
println!("KERN: init gpu");
|
||||||
GPU_DEVICE.clone();
|
let _gpu = GPU_DEVICE.clone();
|
||||||
println!("KERN: init keyboard");
|
println!("KERN: init keyboard");
|
||||||
KEYBOARD_DEVICE.clone();
|
let _keyboard = KEYBOARD_DEVICE.clone();
|
||||||
println!("KERN: init mouse");
|
println!("KERN: init mouse");
|
||||||
MOUSE_DEVICE.clone();
|
let _mouse = MOUSE_DEVICE.clone();
|
||||||
println!("KERN: init trap");
|
println!("KERN: init trap");
|
||||||
trap::init();
|
trap::init();
|
||||||
trap::enable_timer_interrupt();
|
trap::enable_timer_interrupt();
|
||||||
timer::set_next_trigger();
|
timer::set_next_trigger();
|
||||||
board::device_init();
|
board::device_init();
|
||||||
fs::list_apps();
|
fs::list_apps();
|
||||||
//syscall::create_desktop(); //for test
|
gui::init_paint();
|
||||||
task::add_initproc();
|
task::add_initproc();
|
||||||
*DEV_NON_BLOCKING_ACCESS.exclusive_access() = true;
|
*DEV_NON_BLOCKING_ACCESS.exclusive_access() = true;
|
||||||
task::run_tasks();
|
task::run_tasks();
|
||||||
|
@ -48,7 +48,7 @@ impl StackFrameAllocator {
|
|||||||
pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
|
pub fn init(&mut self, l: PhysPageNum, r: PhysPageNum) {
|
||||||
self.current = l.0;
|
self.current = l.0;
|
||||||
self.end = r.0;
|
self.end = r.0;
|
||||||
println!("last {} Physical Frames.", self.end - self.current);
|
// println!("last {} Physical Frames.", self.end - self.current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl FrameAllocator for StackFrameAllocator {
|
impl FrameAllocator for StackFrameAllocator {
|
||||||
|
@ -92,14 +92,14 @@ impl MemorySet {
|
|||||||
// map trampoline
|
// map trampoline
|
||||||
memory_set.map_trampoline();
|
memory_set.map_trampoline();
|
||||||
// map kernel sections
|
// map kernel sections
|
||||||
println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
|
// println!(".text [{:#x}, {:#x})", stext as usize, etext as usize);
|
||||||
println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
|
// println!(".rodata [{:#x}, {:#x})", srodata as usize, erodata as usize);
|
||||||
println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
|
// println!(".data [{:#x}, {:#x})", sdata as usize, edata as usize);
|
||||||
println!(
|
// println!(
|
||||||
".bss [{:#x}, {:#x})",
|
// ".bss [{:#x}, {:#x})",
|
||||||
sbss_with_stack as usize, ebss as usize
|
// sbss_with_stack as usize, ebss as usize
|
||||||
);
|
// );
|
||||||
println!("mapping .text section");
|
// println!("mapping .text section");
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
(stext as usize).into(),
|
(stext as usize).into(),
|
||||||
@ -109,7 +109,7 @@ impl MemorySet {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
println!("mapping .rodata section");
|
// println!("mapping .rodata section");
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
(srodata as usize).into(),
|
(srodata as usize).into(),
|
||||||
@ -119,7 +119,7 @@ impl MemorySet {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
println!("mapping .data section");
|
// println!("mapping .data section");
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
(sdata as usize).into(),
|
(sdata as usize).into(),
|
||||||
@ -129,7 +129,7 @@ impl MemorySet {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
println!("mapping .bss section");
|
// println!("mapping .bss section");
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
(sbss_with_stack as usize).into(),
|
(sbss_with_stack as usize).into(),
|
||||||
@ -139,7 +139,7 @@ impl MemorySet {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
println!("mapping physical memory");
|
// println!("mapping physical memory");
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
(ekernel as usize).into(),
|
(ekernel as usize).into(),
|
||||||
@ -149,7 +149,7 @@ impl MemorySet {
|
|||||||
),
|
),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
println!("mapping memory-mapped registers");
|
//println!("mapping memory-mapped registers");
|
||||||
for pair in MMIO {
|
for pair in MMIO {
|
||||||
memory_set.push(
|
memory_set.push(
|
||||||
MapArea::new(
|
MapArea::new(
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
use alloc::{string::ToString, sync::Arc, vec::Vec};
|
|
||||||
use embedded_graphics::{
|
|
||||||
prelude::{Point, Size},
|
|
||||||
primitives::arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
fs::ROOT_INODE,
|
|
||||||
gui::{Button, Component, IconController, ImageComp, Panel, Terminal},
|
|
||||||
sync::UPIntrFreeCell,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::board::{VIRTGPU_XRES, VIRTGPU_YRES};
|
|
||||||
|
|
||||||
static DT: &[u8] = include_bytes!("../assert/desktop.bmp");
|
|
||||||
|
|
||||||
lazy_static::lazy_static!(
|
|
||||||
pub static ref DESKTOP:UPIntrFreeCell<Arc<dyn Component>> = unsafe {
|
|
||||||
UPIntrFreeCell::new(Arc::new(Panel::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES), Point::new(0, 0))))
|
|
||||||
};
|
|
||||||
pub static ref PAD:UPIntrFreeCell<Option<Arc<Terminal>>> = unsafe {
|
|
||||||
UPIntrFreeCell::new(None)
|
|
||||||
};
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn create_desktop() -> isize {
|
|
||||||
let mut p: Arc<dyn Component + 'static> =
|
|
||||||
Arc::new(Panel::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES), Point::new(0, 0)));
|
|
||||||
let image = ImageComp::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES), Point::new(0, 0), DT, Some(p.clone()));
|
|
||||||
let icon = IconController::new(ROOT_INODE.ls(), Some(p.clone()));
|
|
||||||
p.add(Arc::new(image));
|
|
||||||
p.add(Arc::new(icon));
|
|
||||||
let mut desktop = DESKTOP.exclusive_access();
|
|
||||||
*desktop = p;
|
|
||||||
desktop.paint();
|
|
||||||
drop(desktop);
|
|
||||||
create_terminal();
|
|
||||||
1
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_terminal() {
|
|
||||||
let desktop = DESKTOP.exclusive_access();
|
|
||||||
let arc_t = Arc::new(Terminal::new(
|
|
||||||
Size::new(400, 400),
|
|
||||||
Point::new(200, 100),
|
|
||||||
Some(desktop.clone()),
|
|
||||||
Some("demo.txt".to_string()),
|
|
||||||
"".to_string(),
|
|
||||||
));
|
|
||||||
let text = Panel::new(Size::new(400, 400), Point::new(200, 100));
|
|
||||||
let button = Button::new(
|
|
||||||
Size::new(20, 20),
|
|
||||||
Point::new(370, 10),
|
|
||||||
Some(arc_t.clone()),
|
|
||||||
"X".to_string(),
|
|
||||||
);
|
|
||||||
arc_t.add(Arc::new(text));
|
|
||||||
arc_t.add(Arc::new(button));
|
|
||||||
arc_t.paint();
|
|
||||||
desktop.add(arc_t.clone());
|
|
||||||
let mut pad = PAD.exclusive_access();
|
|
||||||
*pad = Some(arc_t);
|
|
||||||
}
|
|
@ -25,16 +25,13 @@ const SYSCALL_SEMAPHORE_DOWN: usize = 1022;
|
|||||||
const SYSCALL_CONDVAR_CREATE: usize = 1030;
|
const SYSCALL_CONDVAR_CREATE: usize = 1030;
|
||||||
const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
|
const SYSCALL_CONDVAR_SIGNAL: usize = 1031;
|
||||||
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
const SYSCALL_CONDVAR_WAIT: usize = 1032;
|
||||||
const SYSCALL_CREATE_DESKTOP: usize = 2000;
|
|
||||||
mod fs;
|
mod fs;
|
||||||
mod gui;
|
|
||||||
mod process;
|
mod process;
|
||||||
mod sync;
|
mod sync;
|
||||||
mod thread;
|
mod thread;
|
||||||
pub use self::gui::create_desktop;
|
|
||||||
use fs::*;
|
|
||||||
|
|
||||||
pub use gui::PAD;
|
use fs::*;
|
||||||
use process::*;
|
use process::*;
|
||||||
use sync::*;
|
use sync::*;
|
||||||
use thread::*;
|
use thread::*;
|
||||||
@ -68,8 +65,6 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
|||||||
SYSCALL_CONDVAR_CREATE => sys_condvar_create(args[0]),
|
SYSCALL_CONDVAR_CREATE => sys_condvar_create(args[0]),
|
||||||
SYSCALL_CONDVAR_SIGNAL => sys_condvar_signal(args[0]),
|
SYSCALL_CONDVAR_SIGNAL => sys_condvar_signal(args[0]),
|
||||||
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
|
SYSCALL_CONDVAR_WAIT => sys_condvar_wait(args[0], args[1]),
|
||||||
SYSCALL_CREATE_DESKTOP => create_desktop(),
|
|
||||||
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
_ => panic!("Unsupported syscall_id: {}", syscall_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,13 +61,14 @@ pub fn add_timer(expire_ms: usize, task: Arc<TaskControlBlock>) {
|
|||||||
|
|
||||||
pub fn check_timer() {
|
pub fn check_timer() {
|
||||||
let current_ms = get_time_ms();
|
let current_ms = get_time_ms();
|
||||||
let mut timers = TIMERS.exclusive_access();
|
TIMERS.exclusive_session(|timers| {
|
||||||
while let Some(timer) = timers.peek() {
|
while let Some(timer) = timers.peek() {
|
||||||
if timer.expire_ms <= current_ms {
|
if timer.expire_ms <= current_ms {
|
||||||
add_task(Arc::clone(&timer.task));
|
add_task(Arc::clone(&timer.task));
|
||||||
timers.pop();
|
timers.pop();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ pub fn trap_handler() -> ! {
|
|||||||
set_kernel_trap_entry();
|
set_kernel_trap_entry();
|
||||||
let scause = scause::read();
|
let scause = scause::read();
|
||||||
let stval = stval::read();
|
let stval = stval::read();
|
||||||
//println!("into {:?}", scause.cause());
|
// println!("into {:?}", scause.cause());
|
||||||
match scause.cause() {
|
match scause.cause() {
|
||||||
Trap::Exception(Exception::UserEnvCall) => {
|
Trap::Exception(Exception::UserEnvCall) => {
|
||||||
// jump to next instruction anyway
|
// jump to next instruction anyway
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
#![no_main]
|
|
||||||
|
|
||||||
use user_lib::create_desktop;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate user_lib;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub fn main() -> i32 {
|
|
||||||
println!("gui");
|
|
||||||
create_desktop();
|
|
||||||
println!("exit pass.");
|
|
||||||
loop{}
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
|||||||
extern crate user_lib;
|
extern crate user_lib;
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::{fmt::format, string::String, vec::Vec};
|
use alloc::{fmt::format, vec::Vec};
|
||||||
use user_lib::{close, get_time, gettid, open, write, OpenFlags};
|
use user_lib::{close, get_time, gettid, open, write, OpenFlags};
|
||||||
use user_lib::{exit, thread_create, waittid};
|
use user_lib::{exit, thread_create, waittid};
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_main]
|
#![no_main]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(asm)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate user_lib;
|
extern crate user_lib;
|
||||||
|
@ -198,9 +198,7 @@ pub fn condvar_signal(condvar_id: usize) {
|
|||||||
pub fn condvar_wait(condvar_id: usize, mutex_id: usize) {
|
pub fn condvar_wait(condvar_id: usize, mutex_id: usize) {
|
||||||
sys_condvar_wait(condvar_id, mutex_id);
|
sys_condvar_wait(condvar_id, mutex_id);
|
||||||
}
|
}
|
||||||
pub fn create_desktop() {
|
|
||||||
sys_create_desktop();
|
|
||||||
}
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! vstore {
|
macro_rules! vstore {
|
||||||
($var_ref: expr, $value: expr) => {
|
($var_ref: expr, $value: expr) => {
|
||||||
|
@ -154,6 +154,3 @@ pub fn sys_condvar_signal(condvar_id: usize) -> isize {
|
|||||||
pub fn sys_condvar_wait(condvar_id: usize, mutex_id: usize) -> isize {
|
pub fn sys_condvar_wait(condvar_id: usize, mutex_id: usize) -> isize {
|
||||||
syscall(SYSCALL_CONDVAR_WAIT, [condvar_id, mutex_id, 0])
|
syscall(SYSCALL_CONDVAR_WAIT, [condvar_id, mutex_id, 0])
|
||||||
}
|
}
|
||||||
pub fn sys_create_desktop() -> isize {
|
|
||||||
syscall(2000, [0, 0, 0])
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user