diff options
-rw-r--r-- | apps/test.c | 8 | ||||
-rw-r--r-- | apps/wm.c | 14 | ||||
-rw-r--r-- | kernel/features/fs.c | 1 | ||||
-rw-r--r-- | kernel/features/proc.c | 1 | ||||
-rw-r--r-- | kernel/features/syscall.c | 6 | ||||
-rw-r--r-- | libgui/Makefile | 1 | ||||
-rw-r--r-- | libgui/bmp.c | 28 | ||||
-rw-r--r-- | libgui/gui.c | 55 | ||||
-rw-r--r-- | libgui/inc/bmp.h | 39 | ||||
-rw-r--r-- | libgui/inc/gui.h | 4 | ||||
-rwxr-xr-x | run | 2 |
11 files changed, 148 insertions, 11 deletions
diff --git a/apps/test.c b/apps/test.c index dd85ffd..3bbe824 100644 --- a/apps/test.c +++ b/apps/test.c @@ -11,12 +11,8 @@ int main() struct message *msg = msg_receive_loop(); struct window *win = (struct window *)msg->data; - // TODO: Fix window transmitting - printf("\nReceived %d from %d\n", win->x, msg->src); - printf("Received %d from %d\n", win->y, msg->src); - printf("Received %d from %d\n", win->width, msg->src); - printf("Received %d from %d\n", win->height, msg->src); - printf("Received %d from %d\n", win->fb, msg->src); + const u32 color[3] = { 0xff, 0, 0 }; + gui_fill(win, color); while (1) { }; @@ -29,6 +29,7 @@ static struct window *new_window(int x, int y, u16 width, u16 height) win->y = y; win->width = width; win->height = height; + win->vbe = vbe; win->fb = malloc(width * height * (vbe->bpp >> 3)); return win; } @@ -44,11 +45,21 @@ int main(int argc, char **argv) const u32 color[3] = { 0, 0, 0 }; vesa_fill(vbe, color); gui_init("/font/spleen-16x32.psfu"); + gui_load_wallpaper(vbe, "/wall.bmp"); event_map(EVENT_KEYBOARD, onkey); + u32 last_time = 0; struct message *msg; while (1) { // TODO: Remove continuous polling? + /* u32 current_time = time(); */ + /* if (current_time - last_time > 1000 / 60) { // 60Hz */ + /* struct window *win = windows->head->data; */ + /* memcpy(vbe->fb, windows->head->data, */ + /* win->width * win->height * (vbe->bpp >> 3)); */ + /* } */ + /* last_time = current_time; */ + if (!(msg = msg_receive())) { yield(); continue; @@ -57,8 +68,9 @@ int main(int argc, char **argv) switch (msg->type) { case MSG_NEW_WINDOW: printf("New window for pid %d\n", msg->src); - struct window *win = new_window(50, 50, 200, 200); + struct window *win = new_window(0, 0, 200, 200); msg_send(msg->src, MSG_NEW_WINDOW, win); + list_add(windows, win); break; default: printf("Unknown WM request %d from pid %d", msg->type, msg->src); diff --git a/kernel/features/fs.c b/kernel/features/fs.c index f23ccc0..7a9f209 100644 --- a/kernel/features/fs.c +++ b/kernel/features/fs.c @@ -84,6 +84,7 @@ void *read_inode(struct inode *in) data = buffer_read(blocknum); memcpy((u32 *)((u32)buf + (i - 1) * BLOCK_SIZE), data, BLOCK_SIZE); } + /* printf("Loaded %d of %d\n", i + 1, num_blocks); */ } return buf; diff --git a/kernel/features/proc.c b/kernel/features/proc.c index ac62195..d358faa 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -100,6 +100,7 @@ struct proc *proc_current() void proc_send(struct proc *src, struct proc *dest, enum message_type type, void *data) { + // TODO: Use unique key instead of pid for IPC messaging assert(src && dest); struct proc_message *msg = malloc(sizeof(*msg)); msg->src = src; diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 4197985..e876553 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -17,7 +17,7 @@ void syscall_handler(struct regs *r) enum sys num = r->eax; r->eax = 0; - if (num != SYS_RECEIVE && num != SYS_YIELD) + if (num != SYS_RECEIVE && num != SYS_YIELD && num != SYS_TIME) printf("[SYSCALL] %d: ", num); switch (num) { @@ -33,7 +33,7 @@ void syscall_handler(struct regs *r) } case SYS_FREE: { printf("free\n"); - free(r->eax); + free(r->ebx); break; } case SYS_READ: { @@ -75,7 +75,7 @@ void syscall_handler(struct regs *r) break; } case SYS_TIME: { - printf("time\n"); + /* printf("time\n"); */ r->eax = timer_get(); break; } diff --git a/libgui/Makefile b/libgui/Makefile index bcd2016..2638cb0 100644 --- a/libgui/Makefile +++ b/libgui/Makefile @@ -2,6 +2,7 @@ COBJS = vesa.o \ psf.o \ + bmp.o \ gui.o CC = ../cross/opt/bin/i686-elf-gcc LD = ../cross/opt/bin/i686-elf-ld diff --git a/libgui/bmp.c b/libgui/bmp.c new file mode 100644 index 0000000..0b08aeb --- /dev/null +++ b/libgui/bmp.c @@ -0,0 +1,28 @@ +// MIT License, Copyright (c) 2020 Marvin Borner + +#include <bmp.h> +#include <def.h> +#include <mem.h> +#include <print.h> +#include <sys.h> + +struct bmp *bmp_load(char *path) +{ + void *buf = read(path); + if (!buf) + return NULL; + + struct bmp_header *h = buf; + if (h->signature[0] != 'B' || h->signature[1] != 'M') + return NULL; + + struct bmp_info *info = (struct bmp_info *)((u32)buf + sizeof(*h)); + struct bmp *bmp = malloc(sizeof(*bmp)); + bmp->width = info->width; + bmp->height = info->height; + bmp->data = (u8 *)((u32)buf + h->offset); + bmp->bpp = info->bpp; + bmp->pitch = bmp->width * (bmp->bpp >> 3); + + return bmp; +} diff --git a/libgui/gui.c b/libgui/gui.c index e42e0f6..3b918e7 100644 --- a/libgui/gui.c +++ b/libgui/gui.c @@ -1,6 +1,8 @@ // MIT License, Copyright (c) 2020 Marvin Borner // Some GUI functions +#include <assert.h> +#include <bmp.h> #include <gui.h> #include <psf.h> #include <str.h> @@ -38,6 +40,59 @@ void gui_write(struct vbe *vbe, int x, int y, const u32 c[3], char *text) } } +void gui_load_wallpaper(struct vbe *vbe, char *path) +{ + struct bmp *bmp = bmp_load(path); + assert(bmp); + + int bpl = bmp->bpp >> 3; + int x1 = 0; + int x2 = bmp->width; + int y1 = 0; + int y2 = bmp->height; + + // TODO: Support padding with odd widths + /* int pitch = bmp->width * bpl; */ + /* int padding = 1; */ + /* while ((pitch + padding) % 4 != 0) */ + /* padding++; */ + /* int psw = pitch + padding; */ + + int pos1 = x1 * bpl + y1 * vbe->pitch; + u8 *draw = &vbe->fb[pos1]; + u8 *data = bmp->data; + for (int i = 0; i <= y2 - y1; i++) { + for (int j = 0; j <= x2 - x1; j++) { + draw[bpl * j] = data[bpl * j]; + draw[bpl * j + 1] = data[bpl * j + 1]; + draw[bpl * j + 2] = data[bpl * j + 2]; + } + draw += vbe->pitch; + data += bmp->pitch; + } +} + +void gui_draw_rectangle(struct window *win, int x1, int y1, int x2, int y2, const u32 color[3]) +{ + int bpl = win->vbe->bpp >> 3; + + int pos1 = x1 * bpl + y1 * win->vbe->pitch; + u8 *draw = &win->fb[pos1]; + for (int i = 0; i <= y2 - y1; i++) { + for (int j = 0; j <= x2 - x1; j++) { + draw[bpl * j] = color[2]; + draw[bpl * j + 1] = color[1]; + draw[bpl * j + 2] = color[0]; + } + draw += win->vbe->pitch; + } +} + +void gui_fill(struct window *win, const u32 color[3]) +{ + gui_draw_rectangle(win, 0, 0, win->width - 1, win->height - 1, color); +} + void gui_init(char *font_path) { font = psf_parse(read(font_path)); diff --git a/libgui/inc/bmp.h b/libgui/inc/bmp.h new file mode 100644 index 0000000..909bc92 --- /dev/null +++ b/libgui/inc/bmp.h @@ -0,0 +1,39 @@ +// MIT License, Copyright (c) 2020 Marvin Borner + +#ifndef BMP_H +#define BMP_H + +#include <def.h> + +struct bmp_header { + u8 signature[2]; + u32 size; + u32 reserved; + u32 offset; +} __attribute__((packed)); + +struct bmp_info { + u32 size; + u32 width; + u32 height; + u16 planes; + u16 bpp; + u32 compression; + u32 compressed_size; + u32 x_pixel_meter; + u32 y_pixel_meter; + u32 colors; + u32 important_colors; +}; + +struct bmp { + u32 width; + u32 height; + u8 *data; + u32 bpp; + u32 pitch; +}; + +struct bmp *bmp_load(char *path); + +#endif diff --git a/libgui/inc/gui.h b/libgui/inc/gui.h index 5f35372..467496a 100644 --- a/libgui/inc/gui.h +++ b/libgui/inc/gui.h @@ -21,9 +21,13 @@ struct window { int y; u16 width; u16 height; + struct vbe *vbe; u8 *fb; }; +void gui_draw_rectangle(struct window *win, int x1, int y1, int x2, int y2, const u32 color[3]); +void gui_fill(struct window *win, const u32 color[3]); +void gui_load_wallpaper(struct vbe *vbe, char *path); void gui_init(char *font_path); /** @@ -79,7 +79,7 @@ make_build() { make # Create disk image - dd if=/dev/zero of=build/disk.img bs=1k count=16k status=none + dd if=/dev/zero of=build/disk.img bs=1k count=32k status=none sudo mke2fs -q build/disk.img dd if=build/boot.bin of=build/disk.img conv=notrunc status=none cp build/kernel.bin . # For nicer disk img |