Skip to content

Commit 6818d9a

Browse files
committed
Add app/guitestrust
1 parent a32c7b7 commit 6818d9a

File tree

11 files changed

+379
-45
lines changed

11 files changed

+379
-45
lines changed

app/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ include ../common.mk
22

33
APPS=\
44
argstest/argstest.bin \
5-
browser/browser.bin \
65
browser-rs/browser-rs.bin \
6+
browser/browser.bin \
77
dig/dig.bin \
88
fizzbuzz/fizzbuzz.bin \
99
guitest/guitest.bin \
10+
guitestrust/guitestrust.bin \
1011
hello/hello.bin \
1112
httpclient/httpclient.bin \
1213
httpserver/httpserver.bin \

app/guitest/guitest.c

+64-23
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,48 @@ struct __attribute__((packed)) BMPInfoV3Header {
2828
void InitFreeType();
2929

3030
/* freetype_wrapper.c */
31-
void DrawFirstChar(uint32_t *bmp, int w, int x, int y, uint32_t col, const char *s);
31+
void DrawFirstChar(uint32_t* bmp,
32+
int w,
33+
int x,
34+
int y,
35+
uint32_t col,
36+
const char* s);
3237
void DrawString(uint32_t* bmp,
3338
int w,
3439
int x,
3540
int y,
3641
uint32_t col,
3742
const char* s);
3843

39-
int main(int argc, char* argv[]) {
40-
InitFreeType();
44+
struct WindowBuffer {
45+
int fd;
46+
void* file_buf;
47+
uint32_t file_size;
48+
void* bmp_buf;
49+
int width, height;
50+
};
51+
// not valid if file_buf == NULL
52+
53+
struct WindowBuffer
54+
CreateWindowBuffer(int width, int height) {
55+
struct WindowBuffer w;
56+
w.file_buf = NULL;
4157

42-
const int w = 512;
43-
const int h = 256;
4458
uint32_t header_size_with_padding =
4559
(sizeof(struct BMPFileHeader) + sizeof(struct BMPInfoV3Header) + 0xF) &
4660
~0xF; /* header size aligned to 16-byte boundary */
47-
uint32_t file_size = header_size_with_padding + w * h * 4;
61+
62+
uint32_t file_size = header_size_with_padding + width * height * 4;
4863
int fd = open("window.bmp", O_RDWR | O_CREAT, 0664);
64+
if (fd == -1) {
65+
return w;
66+
}
67+
4968
ftruncate(fd, file_size);
50-
void* buf = mmap(NULL, file_size, PROT_WRITE, MAP_SHARED, fd, 0);
51-
if (buf == MAP_FAILED) {
52-
return 1;
69+
void* file_buf = mmap(NULL, file_size, PROT_WRITE, MAP_SHARED, fd, 0);
70+
71+
if (file_buf == MAP_FAILED) {
72+
return w;
5373
}
5474

5575
struct BMPFileHeader file_header;
@@ -62,8 +82,8 @@ int main(int argc, char* argv[]) {
6282
struct BMPInfoV3Header info_header;
6383
bzero(&info_header, sizeof(info_header));
6484
info_header.info_size = sizeof(info_header);
65-
info_header.xsize = w;
66-
info_header.ysize = -h;
85+
info_header.xsize = width;
86+
info_header.ysize = -height;
6787
info_header.planes = 1;
6888
info_header.bpp = 32;
6989
info_header.compression_type = 3;
@@ -75,23 +95,44 @@ int main(int argc, char* argv[]) {
7595
info_header.g_mask = 0x00FF00;
7696
info_header.b_mask = 0x0000FF;
7797

78-
memcpy(&buf[0], &file_header, sizeof(file_header));
79-
memcpy(&buf[sizeof(file_header)], &info_header, sizeof(info_header));
98+
memcpy(&file_buf[0], &file_header, sizeof(file_header));
99+
memcpy(&file_buf[sizeof(file_header)], &info_header, sizeof(info_header));
100+
101+
w.fd = fd;
102+
w.file_buf = file_buf;
103+
w.file_size = file_size;
104+
w.bmp_buf = &file_buf[header_size_with_padding];
105+
w.width = width;
106+
w.height = height;
107+
108+
return w;
109+
}
110+
111+
void FlushWindowBuffer(struct WindowBuffer* w) {
112+
if (!w || !w->file_buf)
113+
return;
114+
msync(w->file_buf, w->file_size, MS_SYNC);
115+
}
116+
117+
int main(int argc, char* argv[]) {
118+
InitFreeType();
119+
120+
struct WindowBuffer w = CreateWindowBuffer(512, 256);
121+
122+
if (!w.file_buf) {
123+
return 1;
124+
}
80125

81-
uint32_t* bmp = &buf[header_size_with_padding];
126+
uint32_t* bmp = w.bmp_buf;
82127

83-
for (int y = 0; y < h; y++) {
84-
for (int x = 0; x < w; x++) {
85-
uint8_t pixel_bgra[4] = {0, y, x/2, 0};
86-
bmp[y * w + x] = *(uint32_t*)pixel_bgra;
128+
for (int y = 0; y < w.height; y++) {
129+
for (int x = 0; x < w.width; x++) {
130+
uint8_t pixel_bgra[4] = {0, y % 64, x % 64, 0};
131+
bmp[y * w.width + x] = *(uint32_t*)pixel_bgra;
87132
}
88133
}
89-
int px = 100;
90-
int py = 100;
91-
DrawString(bmp, w, 32, 64, 0xFFFFFF, "Welcome to liumOS!");
92-
DrawString(bmp, w, 32, 96, 0xFFFFFF, "liumOSへようこそ!");
93134

94-
msync(buf, file_size, MS_SYNC);
135+
FlushWindowBuffer(&w);
95136

96137
return 0;
97138
}

app/guitestrust/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/target
2+
*.swp
3+
*.o

app/guitestrust/Cargo.lock

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/guitestrust/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "guitestrust"
3+
version = "0.1.0"
4+
authors = ["hikalium <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
liumlib = { path = "../liumlib" }

app/guitestrust/Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
TARGET=guitestrust
2+
TARGET_BIN=$(TARGET).bin
3+
default: $(TARGET_BIN)
4+
5+
include ../../common.mk
6+
7+
CARGO:= export GIT_HASH='$(shell ./githash.sh)' && \
8+
export LLVM_CC="$(LLVM_CC)" && \
9+
export LLVM_AR="$(LLVM_AR)" && \
10+
cargo
11+
12+
CARGO_ARGS:= -vv --target=../liumlib/x86_64-unknown-elf.json --release \
13+
-Z build-std=core,alloc \
14+
-Z build-std-features=compiler-builtins-mem
15+
16+
$(TARGET_BIN) : .FORCE
17+
$(CARGO) build $(CARGO_ARGS)
18+
cp target/x86_64-unknown-elf/release/$(TARGET) $(TARGET_BIN)
19+
20+
.PHONY : install clean dump clippy .FORCE
21+
22+
install: $(TARGET_BIN)
23+
clean:
24+
-rm -r target
25+
-rm *.bin
26+
dump: $(TARGET_BIN)
27+
objdump -d target/x86_64-unknown-elf/release/$(TARGET)
28+
clippy :
29+
$(CARGO) clippy $(CARGO_ARGS)
30+
31+
test:
32+
make

app/guitestrust/githash.sh

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
printf `git rev-parse HEAD`
6+
7+
git add -N .
8+
set +e
9+
git diff --exit-code --quiet
10+
if [[ $? -eq 1 ]]; then
11+
printf ' (modified)'
12+
fi

app/guitestrust/src/main.rs

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
#![no_std]
2+
#![no_main]
3+
#![feature(rustc_private)]
4+
5+
extern crate alloc;
6+
extern crate compiler_builtins;
7+
8+
use compiler_builtins::mem::memcpy;
9+
use core::mem::size_of;
10+
use core::ptr::null_mut;
11+
12+
#[repr(packed)]
13+
struct BMPFileHeader {
14+
signature: [u8; 2],
15+
file_size: u32,
16+
reserved: u32,
17+
offset_to_data: u32, // offset in file to pixels
18+
}
19+
20+
#[repr(packed)]
21+
struct BMPInfoV3Header {
22+
info_size: u32, // = 0x38 for Size of data follows this header
23+
xsize: i32,
24+
ysize: i32,
25+
planes: u16, // = 1
26+
bpp: u16, // = 32
27+
compression_type: u32, // = 3: bit field, {B,G,R,A}
28+
image_data_size: u32, // Size of data which follows this header
29+
pixel_per_meter_x: u32, // = 0x2E23 = 300 ppi
30+
pixel_per_meter_y: u32,
31+
padding: u64,
32+
r_mask: u32,
33+
g_mask: u32,
34+
b_mask: u32,
35+
}
36+
37+
use liumlib::*;
38+
39+
struct WindowBuffer {
40+
fd: i32,
41+
file_buf: *mut u8,
42+
file_size: usize,
43+
bmp_buf: *mut u8,
44+
width: usize,
45+
height: usize,
46+
}
47+
48+
trait BitmapImageBuffer {
49+
fn bytes_per_pixel(&self) -> usize;
50+
fn pixels_per_line(&self) -> usize;
51+
fn width(&self) -> usize;
52+
fn height(&self) -> usize;
53+
fn buf(&self) -> *mut u8;
54+
fn flush(&self);
55+
}
56+
57+
impl BitmapImageBuffer for WindowBuffer {
58+
fn bytes_per_pixel(&self) -> usize {
59+
4
60+
}
61+
fn pixels_per_line(&self) -> usize {
62+
self.width
63+
}
64+
fn width(&self) -> usize {
65+
self.width
66+
}
67+
fn height(&self) -> usize {
68+
self.height
69+
}
70+
fn buf(&self) -> *mut u8 {
71+
self.bmp_buf
72+
}
73+
fn flush(&self) {
74+
flush_window_buffer(&self);
75+
}
76+
}
77+
78+
fn create_window_buffer(width: usize, height: usize) -> core::result::Result<WindowBuffer, ()> {
79+
// Open the window file
80+
let fd = open("window.bmp", liumlib::O_RDWR | O_CREAT, 0664);
81+
if fd.is_none() {
82+
return Err(());
83+
}
84+
let fd = fd.unwrap();
85+
86+
// resize the file to store the bmp data
87+
let header_size_with_padding =
88+
(size_of::<BMPFileHeader>() + size_of::<BMPInfoV3Header>() + 0xF) & !0xF; /* header size aligned to 16-byte boundary */
89+
let file_size = header_size_with_padding + width * height * 4;
90+
91+
ftruncate(&fd, file_size);
92+
let file_buf = mmap(null_mut(), file_size, PROT_WRITE, MAP_SHARED, &fd, 0);
93+
94+
if file_buf == MAP_FAILED {
95+
return Err(());
96+
}
97+
98+
let file_header = BMPFileHeader {
99+
signature: [b'B', b'M'],
100+
file_size: file_size as u32,
101+
offset_to_data: header_size_with_padding as u32,
102+
reserved: 0,
103+
};
104+
105+
let info_header: BMPInfoV3Header = BMPInfoV3Header {
106+
info_size: size_of::<BMPInfoV3Header>() as u32,
107+
xsize: width as i32,
108+
ysize: -(height as i32),
109+
planes: 1,
110+
bpp: 32,
111+
compression_type: 3,
112+
image_data_size: file_header.file_size
113+
- size_of::<BMPFileHeader>() as u32
114+
- size_of::<BMPInfoV3Header>() as u32,
115+
pixel_per_meter_y: 0x2E23, /* 300ppi */
116+
pixel_per_meter_x: 0x2E23, /* 300ppi */
117+
padding: 0,
118+
r_mask: 0xFF0000,
119+
g_mask: 0x00FF00,
120+
b_mask: 0x0000FF,
121+
};
122+
123+
unsafe {
124+
memcpy(
125+
file_buf,
126+
&file_header as *const BMPFileHeader as *const u8,
127+
size_of::<BMPFileHeader>(),
128+
);
129+
memcpy(
130+
file_buf.add(size_of::<BMPFileHeader>()),
131+
&info_header as *const BMPInfoV3Header as *const u8,
132+
size_of::<BMPInfoV3Header>(),
133+
);
134+
}
135+
136+
Ok(WindowBuffer {
137+
fd: fd.number(),
138+
file_buf: file_buf,
139+
file_size: file_size,
140+
bmp_buf: unsafe { file_buf.add(header_size_with_padding) },
141+
width: width,
142+
height: height,
143+
})
144+
}
145+
146+
fn flush_window_buffer(w: &WindowBuffer) {
147+
msync(w.file_buf, w.file_size, MS_SYNC);
148+
}
149+
150+
fn draw_test_pattern<T: BitmapImageBuffer>(buf: &T) {
151+
for y in 0..buf.height() {
152+
for x in 0..buf.width() {
153+
for i in 0..buf.bytes_per_pixel() {
154+
unsafe {
155+
let p = buf
156+
.buf()
157+
.add((y * buf.pixels_per_line() + x) * buf.bytes_per_pixel());
158+
// ARGB
159+
// *p.add(3) = alpha;
160+
*p.add(2) = (x * 4) as u8;
161+
*p.add(1) = (y * 4) as u8;
162+
*p.add(0) = (x * x / 32 + y * y / 32) as u8;
163+
}
164+
}
165+
}
166+
}
167+
buf.flush();
168+
}
169+
170+
entry_point!(main);
171+
fn main() {
172+
println!("Welcome to shelium, a simple shell for liumOS written in Rust!");
173+
let w = create_window_buffer(512, 256);
174+
if w.is_err() {
175+
println!("Failed to create window");
176+
return;
177+
}
178+
let w = w.unwrap();
179+
println!("Window created");
180+
draw_test_pattern(&w);
181+
}

0 commit comments

Comments
 (0)