From caf9f821294a31022562ecb7c2863dcbc7066dab Mon Sep 17 00:00:00 2001 From: Kevin Alavik Date: Sun, 25 Feb 2024 12:50:05 +0100 Subject: [PATCH] Made cursor support and window support! --- ramdisk/etc/graphics/cursor_normal.tga | Bin 844 -> 939 bytes ramdisk/etc/graphics/window.tga | Bin 0 -> 93551 bytes src/corelib/stdlib.c | 10 +++ src/corelib/stdlib.h | 4 + src/kernel/boot.c | 3 - src/system/drivers/mouse.c | 74 +++++++++++++---- src/system/pit/pit.c | 9 +++ src/system/utilities/irqs.h | 21 ----- src/system/wm/windows.c | 106 +++++++++++++++++++++++++ src/system/wm/windows.h | 46 +++++++++++ src/system/wm/wm.c | 34 +++----- src/system/wm/wm.h | 13 +++ tools/boot.sh | 2 +- 13 files changed, 258 insertions(+), 64 deletions(-) create mode 100644 ramdisk/etc/graphics/window.tga create mode 100644 src/corelib/stdlib.c delete mode 100644 src/system/utilities/irqs.h create mode 100644 src/system/wm/windows.c create mode 100644 src/system/wm/windows.h diff --git a/ramdisk/etc/graphics/cursor_normal.tga b/ramdisk/etc/graphics/cursor_normal.tga index 3eb74cbef1cd0fd1ea360154c9ea01c8b28005fa..b78816b4741f050146a5d5b3136d7a8a1da473d9 100644 GIT binary patch literal 939 zcmbW0%Sr-q6vj_#W%UML=wj3=5f{CI!GKhBqbKM+?D7I#>_QNPPf3BmK%h5k{I=MjH=wuhHGghv*J8 zRBn+DUR3^sUFwaixs7?+7Q*@tUX}IqjPR%Gi7Kfh|An`3X(r?fZK^P}L~^(n?BY6r z4uUO+dVFjX8Vo}&YJu2p*d**w9Hp2i;Pf2BE=p!*rC~%7f0GoHZ6xP3kzImgE6C;q z<{(`H^NyM0#=QL^_^B9h8t_r_;q0@ZH9(RxpW71EG%%$;{~G_rn96HyWxcTBtU61J LbDIlJv5=J?3le1R literal 844 zcmb7?OAdlS42CBzU3mnTZgk-R++jjuH1QR011LV?()Tl*!4r=Bzfves5=t_i_G?S0 zGsaZSN7@Eoz43xse%Y~#@B5vn6cAsO_j#UYi+x*Esi7V=v5ugTm(}rJ*$GeLk$*%2 zTL}>U5VHak0(}=ZHa7VBjlF3w7jV^JA>g7xDB!HYQou=rm4LK&MA)@}gU;9p*lWOl zgvjLtJ~sk0Jx6-fTpI+O*{={aJw#D5gG+m7jd@`RphcgQOcfrK69vfw-a!s<0)GLo dlMS(Q`G?L1<7GUYI8%4z4*Jbm*X=ni^9D|)-39;v diff --git a/ramdisk/etc/graphics/window.tga b/ramdisk/etc/graphics/window.tga new file mode 100644 index 0000000000000000000000000000000000000000..21b14f67673b05948b0ab1d12d89a6cc9e61abab GIT binary patch literal 93551 zcmeI5%Z}qj6oxBlR;=I+Sh9g<$Yzj6LLhMy@4;o3N&3dX^aTm_Xrw{27;cX+OO`Cy z&qMG4h5wVWowBRDs~vl$Q}tzGCyu*L`P6^@^Ve}X?cAGg^Ljk{YyNol&b$7_ix)n& z`9oj0#bV)|o#L-}{ifry)oSH+?yNcY`Sa)AM>fxNZ1?lm*7V9b?<1S1I%cQzElu#3 z|H<5i9O0_h*1L81g?+qjx2*B%GQB_h`=5XPT&|Xt=7?RQj#%^Unc?v<&92pvhh|dm zLPK|>1BdF^T3tM9-dVT9&W`St%A)h9GHLH3Ce1&cPFY8-%Xg!D$GU){#(Q_8Qzy+p zTKDcor|zVuCP$Y+^`yZ^z)1#q1OLroFnN^T*wNR?V#enojK?R>bLESfhDtB{WP{Tt zi_Wn@l=zDbSd*8{yW2KoiG0G$?c@nb5*OP%(HD(;xvuYKQMKjH)ck=QGIHy>d|i-xBvfO;cSqL-_7!^RSmU5PF6KI*0F4v)k$qB>fEVpnbk>cnT1nDkXfD77BSij&&u)MS&SM_Y63Gl18W{LYMyvo z_*BP-?#D?lKdTFG4ef*eZk&GD@ZpncFbvJM!6$(`@JZht_ynK$ty^2lQZ0dW-oYn* zu;3GX^6~~WvD24w_ynI+S!9F~7TP`_TJlcd4s>ka9ry&FY*R0}m|RRQ4(g?SKm@B! zTiHVF^j(Ed@CkeZpHwPK_i-vHMECt5fn)JWA20X>pIpZyHNSupZ~{)^xwejxtMHJDVV!fQ$A$EuzVyFEnn3gz()P~^`_yj(I zPvDbS-EW+l9~=wE!m)5H91F+x@1fume3Eis37mivaH1&S`JKL=#wYkBWsU((zzH}R zHWwv!h#g{w*x`4#V)Kx3YUOY&91F+7v2ZLLo3_@Rywk6X;uCxlC3V(nTZ~{&g1*`?_*SGKqK1r$hffH~7PKMQni5+5x*dca!2BA9_)#q{Q zpl~c43&+B-@Ch7ybG?te6Za9hxPLzipWu@ir*>=V-~^n2lXza~#!B}yu|w<-JH!sp z7gtfR{jbpNBhO{vla$&PH~}Z%WLOQ9*dca^9b$)P-@0>ieI93i4#&c=a4Z}PpTM#G zdM7@?Cn+^xZ~{)iNv$MV_gH(vO69h}C-@{~o&iq42{;)xA0>8(9b$*rVZD89E;3HN z9FB!!;aE5pj)h~>)`pUI`n6Gff=^=n(Y=oVPNu?%t^2sB{OjhfdX3{~YgBEyGmY-S zYPC}1W41n1>uUUwu!4p7!t__@CH=c~cdC&-oP0#g!m(_v1pzZXDFlvmNr#QW>96ou z23=#&>`!`yCuUIIG}DvXB4m5fS~>pZ^EF1B=NkF33HeeKEJlzqub}a>%8p+w7Cv%V zXIo-e>Rt60P7q;Vo*$MBeA&PU0EIIj04N*)Uy}mzO97_tB<|d$hBu-C`_gbO#i&1N zX7@{JRlR^neh^8K`y_|LlLG(%0A*4iDQ`3G-{Oco1E5iPsuY^aOP7kOAvaP{Lc;34 zja*ET7QiY$SS=a&@=D0tfeZi&zn2043J1UgQb3+5AXt<$zGU3aB0wll2*t*g0uu$M z{3b#%q{DFWafSg3XMhJpMm#e1-7lj{##4F3sa$ERW~nz8KG|H7XUmx>#Mlr3zyM`O zKz8-e~Q25Ll02B@YYLuA*AkdU1{7eEin(|DV(zKun&ZMWX zdzDHnfF4n)m3lWa7V8Lqy3C{@y`%vmi`c36w~UDIT!G3%z;@1IWGMP^XQ%5)l=8pr?u0F*^} zsgY62c~mkpWq?{^ny54x89p%HYQc@5tO0MIhA+zGKk3wtEO}4qBGZ{`>TCl50D!W~ z_ov98dce|6}(TMUg3= zqyhy1001Oq$tm!gRI1>-{RtGwNmF + +static unsigned long int next = 1; + +int rand(void) { + next = next * 1103515245 + 12345; + return (unsigned int)(next / 65536) % 32768; +} + +void srand(unsigned int seed) { next = seed; } \ No newline at end of file diff --git a/src/corelib/stdlib.h b/src/corelib/stdlib.h index f15b217..19feda5 100644 --- a/src/corelib/stdlib.h +++ b/src/corelib/stdlib.h @@ -4,4 +4,8 @@ #include #include +int rand(void); + +void srand(unsigned int seed); + #endif // __STDLIB_H__ \ No newline at end of file diff --git a/src/kernel/boot.c b/src/kernel/boot.c index fbbb909..6bb8233 100644 --- a/src/kernel/boot.c +++ b/src/kernel/boot.c @@ -8,7 +8,6 @@ #include #include #include -#include #include volatile struct limine_module_request mod_request = { @@ -43,8 +42,6 @@ void init_boot(int debug_info) { dprintf("[\e[0;32mSystem\e[0m] Initialized Mouse\n"); init_keyboard(); dprintf("[\e[0;32mSystem\e[0m] Initialized Keyboard\n"); - register_irqs(); - dprintf("[\e[0;32mSystem\e[0m] Registered IRQs\n"); rd = init_rd(); if (rd == NULL) { diff --git a/src/system/drivers/mouse.c b/src/system/drivers/mouse.c index 28742fb..2f67356 100644 --- a/src/system/drivers/mouse.c +++ b/src/system/drivers/mouse.c @@ -1,4 +1,3 @@ -// Credits to https://github.com/asterd-og/BlazarOS #include "mouse.h" uint8_t mouse_state = 0; @@ -7,6 +6,10 @@ uint8_t mouse_bytes[3] = {0, 0, 0}; uint32_t mouse_x = 0; uint32_t mouse_y = 0; +uint32_t old_pixels[50][50]; +uint32_t old_mouse_x = 0; +uint32_t old_mouse_y = 0; + int32_t mouse_wrap_x = 0; int32_t mouse_wrap_y = 0; @@ -15,6 +18,9 @@ bool mouse_right_pressed = false; bool mouse_moved = false; +char *mouse_img = NULL; +uint32_t mouse_img_size = 0; + void mouse_wait_write() { while ((inb8(0x64) & 2) != 0) { ; @@ -39,6 +45,52 @@ uint8_t mouse_read() { return inb8(0x60); } +void draw_mouse(int x, int y) { + if (mouse_img == NULL || mouse_img_size == 0) { + vfs_op_status status = driver_read( + vfs, 0x00000000, "/etc/graphics/cursor_normal.tga", &mouse_img); + if (status == STATUS_OK) { + mouse_img_size = + vfs_get_file_size(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga"); + } else { + return; + } + } + + for (int i = 0; i < 50; i++) { + for (int j = 0; j < 50; j++) { + int pixel_x = x + i; + int pixel_y = y + j; + + old_pixels[i][j] = *(uint32_t *)(framebuffer->address + + pixel_x * (framebuffer->bpp >> 3) + + pixel_y * framebuffer->pitch); + } + } + + draw_tga_from_raw(x, y, mouse_img, mouse_img_size); +} + +void remove_mouse(int x, int y) { + for (int i = 0; i < 50; i++) { + for (int j = 0; j < 50; j++) { + int pixel_x = x + i; + int pixel_y = y + j; + + uint32_t old_pixel = old_pixels[i][j]; + + if (old_pixel != 0) { + uint32_t *framebuffer_address = + (uint32_t *)(framebuffer->address + + pixel_x * (framebuffer->bpp >> 3) + + pixel_y * framebuffer->pitch); + + *framebuffer_address = old_pixel; + } + } + } +} + void mouse_update(int8_t accel_x, int8_t accel_y) { if (mouse_wrap_x + accel_x <= 0) { mouse_wrap_x = 0; @@ -64,18 +116,11 @@ void mouse_update(int8_t accel_x, int8_t accel_y) { mouse_y = (uint32_t)mouse_wrap_y; if (should_draw_cursor) { - char *img; - uint32_t size; - - vfs_op_status status; - - status = - driver_read(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga", &img); - - if (status == STATUS_OK) { - size = - vfs_get_file_size(vfs, 0x00000000, "/etc/graphics/cursor_normal.tga"); - draw_tga_from_raw(mouse_x, mouse_y, img, size); + if (old_mouse_x != mouse_x || old_mouse_y != mouse_y) { + remove_mouse(old_mouse_x, old_mouse_y); + draw_mouse(mouse_x, mouse_y); + old_mouse_x = mouse_x; + old_mouse_y = mouse_y; } } } @@ -96,7 +141,6 @@ void mouse_handler(int_frame_t *frame) { return; } switch (mouse_state) { - // Packet state case 0: mouse_wait_read(); mouse_bytes[0] = mouse_read(); @@ -146,4 +190,4 @@ void mouse_init() { mouse_read(); irq_register(12, mouse_handler); -} \ No newline at end of file +} diff --git a/src/system/pit/pit.c b/src/system/pit/pit.c index bd92678..fa0de93 100644 --- a/src/system/pit/pit.c +++ b/src/system/pit/pit.c @@ -1,9 +1,11 @@ #include "pit.h" +#include #include #include #include #include #include +#include uint64_t uptime_secs; uint16_t uptime_milis; @@ -58,12 +60,19 @@ void pit_set_count(uint16_t count) { return; } +void pit_handler(int_frame_t *frame) { + cur_frame = frame; + update_all_windows(); + pit_int(); +} + void pit_init() { pit_set_count(0); pit_set_divisor(1193182 / 1000); countdown = 0; uptime_milis = 0; uptime_secs = 0; + irq_register(0, pit_handler); } uint64_t pit_get_uptime_secs() { return uptime_secs; } diff --git a/src/system/utilities/irqs.h b/src/system/utilities/irqs.h deleted file mode 100644 index 295cb3d..0000000 --- a/src/system/utilities/irqs.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __IRQS_H__ -#define __IRQS_H__ - -#include -#include -#include -#include -#include -#include -#include - -#include - -void pit_handler(int_frame_t *frame) { - cur_frame = frame; - pit_int(); -} - -void register_irqs() { irq_register(0, pit_handler); } - -#endif // __IRQS_H_ \ No newline at end of file diff --git a/src/system/wm/windows.c b/src/system/wm/windows.c new file mode 100644 index 0000000..926304b --- /dev/null +++ b/src/system/wm/windows.c @@ -0,0 +1,106 @@ +#include "windows.h" + +window_t windows[MAX_WINDOWS]; +int num_windows = 0; + +void spawn_window(window_t *window) { + if (num_windows < MAX_WINDOWS) { + window->buffer = malloc(window->width * window->height * sizeof(uint32_t)); + window->old_buffer = + malloc(window->width * window->height * sizeof(uint32_t)); + if (window->buffer == NULL || window->old_buffer == NULL) { + dprintf("Failed to allocate memory for window buffer\n"); + return; + } + + memset(window->buffer, 0xFFFFFFFF, + window->width * window->height * sizeof(uint32_t)); + memcpy(window->old_buffer, window->buffer, + window->width * window->height * sizeof(uint32_t)); + + int i, j; + uint32_t pixel; + + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + + update_window(window); + } else { + dprintf("Maximum number of windows reached\n"); + } +} + +void update_window(window_t *window) { + int i, j; + uint32_t pixel; + + if (!window->initialized) { + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + + window->initialized = 1; + } else { + for (i = 0; i < window->height; i++) { + for (j = 0; j < window->width; j++) { + pixel = window->buffer[i * window->width + j]; + uint8_t alpha = (pixel & ALPHA_MASK) >> ALPHA_SHIFT; + uint8_t red = (pixel & RED_MASK) >> RED_SHIFT; + uint8_t green = (pixel & GREEN_MASK) >> GREEN_SHIFT; + uint8_t blue = (pixel & BLUE_MASK) >> BLUE_SHIFT; + put_pixel_rgba(window->x + j, window->y + i, red, green, blue, alpha); + } + } + + char *img; + uint32_t size; + vfs_op_status status; + + status = driver_read(vfs, 0x00000000, DEFAULT_WIN_DEC, &img); + if (status == STATUS_OK) { + size = vfs_get_file_size(vfs, 0x00000000, DEFAULT_WIN_DEC); + draw_tga_from_raw(window->x, window->y, img, size); + } + } +} + +void update_all_windows() { + for (int i = 0; i < num_windows; i++) { + update_window(&windows[i]); + } +} diff --git a/src/system/wm/windows.h b/src/system/wm/windows.h new file mode 100644 index 0000000..b4afd45 --- /dev/null +++ b/src/system/wm/windows.h @@ -0,0 +1,46 @@ +#ifndef __WINDOWS_H__ +#define __WINDOWS_H__ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_WINDOWS 100 + +#define WIN_WIDTH 688 +#define WIN_HEIGHT 417 + +#define ALPHA_MASK 0xFF000000 +#define RED_MASK 0x00FF0000 +#define GREEN_MASK 0x0000FF00 +#define BLUE_MASK 0x000000FF + +#define ALPHA_SHIFT 24 +#define RED_SHIFT 16 +#define GREEN_SHIFT 8 +#define BLUE_SHIFT 0 + +#define DEFAULT_WIN_DEC "/etc/graphics/window.tga" + +typedef struct { + char *title; + int x; + int y; + int width; + int height; + uint32_t *buffer; + uint32_t *old_buffer; + int initialized; +} window_t; + +extern window_t windows[MAX_WINDOWS]; +extern int num_windows; + +void spawn_window(window_t *window); +void update_window(window_t *window); +void update_all_windows(); +#endif // __WINDOWS_H__ diff --git a/src/system/wm/wm.c b/src/system/wm/wm.c index ef28608..c53322f 100644 --- a/src/system/wm/wm.c +++ b/src/system/wm/wm.c @@ -1,15 +1,4 @@ #include "wm.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #define DHEIGHT 25 @@ -28,21 +17,18 @@ void init_taskbar() { } void init_wm() { + should_draw_cursor = true; + keyboard.out = false; + init_wallpaper(); init_taskbar(); - char *img; - uint32_t size; - - vfs_op_status status; + window_t test_window; + test_window.title = "Test Window"; + test_window.x = 100; + test_window.y = 100; + test_window.width = WIN_WIDTH; + test_window.height = WIN_HEIGHT; - status = driver_read(vfs, 0x00000000, "/root/test/test.tga", &img); - - if (status == STATUS_OK) { - size = vfs_get_file_size(vfs, 0x00000000, "/root/test/test.tga"); - draw_tga_from_raw(0, 0, img, size); - } - - should_draw_cursor = true; - keyboard.out = true; + spawn_window(&test_window); } \ No newline at end of file diff --git a/src/system/wm/wm.h b/src/system/wm/wm.h index b4da9f4..47018a8 100644 --- a/src/system/wm/wm.h +++ b/src/system/wm/wm.h @@ -1,8 +1,21 @@ #ifndef __GUI_H__ #define __GUI_H__ +#include +#include +#include +#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include extern bool should_draw_cursor; diff --git a/tools/boot.sh b/tools/boot.sh index c290051..be2158b 100755 --- a/tools/boot.sh +++ b/tools/boot.sh @@ -2,4 +2,4 @@ bash $(pwd)/tools/build.sh -qemu-system-x86_64 -vga std -debugcon stdio -hda image.iso "${@}" +qemu-system-x86_64 --enable-kvm -vga std -debugcon stdio -hda image.iso "${@}"