setos

拙OS
Log | Files | Refs | LICENSE

commit 6fb64f2d4d18be0a39c8906ca2b5da10f4fed9ad
parent bbb1f60e32f34950397667c50757d3a792eb6852
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat,  6 Apr 2024 13:54:04 +0900

draw mouse pointer

Diffstat:
Msys/include/draw.h | 16+++++++++++++---
Msys/src/Makefile | 11++++++-----
Msys/src/kernel/draw.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
Msys/src/kernel/main.c | 35++++++++++++++++++++++++++++++++++-
Dsys/src/kernel/start.s | 7-------
5 files changed, 156 insertions(+), 37 deletions(-)

diff --git a/sys/include/draw.h b/sys/include/draw.h @@ -25,7 +25,7 @@ typedef struct Image { #define MAX_CHILD_WIN 16 // TODO: dynamically allocate. typedef struct Window { - uint32 *fb; // for the root window only. + uint32 *fb; // for the root window only. TODO: I think children need fb for optimization. int ppsl; RGBA32 fg; RGBA32 bg; @@ -36,12 +36,22 @@ typedef struct Window { int nchildren; } Window; +typedef struct Mouse { + Point size; + Point pos; + RGBA32 *hidden; + RGBA32 *img; +} Mouse; + int init_root_window(uint32 *fb_base, int hres, int vres, int ppsl, EFI_GRAPHICS_PIXEL_FORMAT pf); extern void (* pixel)(Window *dst, Point p, RGBA32 col); +extern RGBA32 (* get_pixel)(Window *win, Point at); void line(Window *dst, Point p0, Point p1, RGBA32 col); // i is the thickness of the border. // i = 0: one pixel line, i > 0: inside the border, i < 0: outside the border. void border(Window *dst, Rectangle r, int i, RGBA32 col); void fill(Window *dst, Rectangle r, RGBA32 col); void clear(Window *dst); -int make_window(Window *parent, Window *child, Point at, Point size, RGBA32 fg, RGBA32 bg); -\ No newline at end of file +int make_window(Window *parent, Window *child, Point at, Point size, RGBA32 fg, RGBA32 bg); +void draw_mouse(Window *dst, Mouse *mouse); +void clear_mouse(Window *dst, Mouse *mouse); +\ No newline at end of file diff --git a/sys/src/Makefile b/sys/src/Makefile @@ -1,4 +1,5 @@ TARGETS = boot kernel libc +ARCH = amd64 BOOTCC = x86_64-w64-mingw32-gcc BOOTCFLAGS = -I ../include \ @@ -27,12 +28,12 @@ boot/boot.efi: boot/boot.dll boot/boot.dll: boot/boot.c boot/utils.c $(BOOTCC) $(BOOTCFLAGS) -o $@ boot/boot.c boot/utils.c -kernel/main.elf: kernel/start.o kernel/main.o kernel/draw.o kernel/alloc.o kernel/console.o kernel/memmap.ld ../lib/libc.a +kernel/main.elf: kernel/$(ARCH)/start.o kernel/main.o kernel/draw.o kernel/alloc.o kernel/console.o kernel/memmap.ld ../lib/libc.a $(LD) $(LDFLAGS) -e kernel_start -T kernel/memmap.ld -o $@ \ - kernel/start.o kernel/main.o kernel/draw.o kernel/alloc.o kernel/console.o \ + kernel/$(ARCH)/start.o kernel/main.o kernel/draw.o kernel/alloc.o kernel/console.o \ -lc -kernel/start.o: kernel/start.s - $(CC) $(CFLAGS) -c -o $@ kernel/start.s +kernel/$(ARCH)/start.o: kernel/$(ARCH)/start.s + $(CC) $(CFLAGS) -c -o $@ kernel/$(ARCH)/start.s kernel/main.o: kernel/main.c ../include/uefi.h ../include/libc.h ../include/draw.h ../include/console.h $(CC) $(CFLAGS) -c -o $@ kernel/main.c kernel/draw.o: kernel/draw.c ../include/uefi.h ../include/libc.h ../include/draw.h ../include/console.h @@ -70,5 +71,5 @@ gdb: disk.img OVMF.fd clean: rm -rf disk.img image rm -f boot/boot.efi boot/boot.dll - rm -f kernel/*.o kernel/main.elf + rm -f kernel/*.o kernel/$(ARCH)/*.o kernel/main.elf rm -rf libc/*.o ../lib diff --git a/sys/src/kernel/draw.c b/sys/src/kernel/draw.c @@ -6,23 +6,29 @@ Window root_window; void (* pixel)(Window *dst, Point p, RGBA32 col); +RGBA32 (*get_pixel)(Window *win, Point at); + static void pixelRedGreenBlueReserved(Window *dst, Point p, RGBA32 col); static void pixelBlueGreenRedReserved(Window *dst, Point p, RGBA32 col); +static RGBA32 get_pixelRedGreenBlueReserved(Window *win, Point at); +static RGBA32 get_pixelBlueGreenRedReserved(Window *win, Point at); int init_root_window(uint32 *fb_base, int hres, int vres, int ppsl, EFI_GRAPHICS_PIXEL_FORMAT pf) { if (pf == PixelRedGreenBlueReserved8BitPerColor) { pixel = pixelRedGreenBlueReserved; + get_pixel = get_pixelRedGreenBlueReserved; } else if (pf == PixelBlueGreenRedReserved8BitPerColor) { pixel = pixelBlueGreenRedReserved; + get_pixel = get_pixelBlueGreenRedReserved; } else { strcpy(err.ename, "pixel format not supported."); return -1; } root_window.fb = fb_base; root_window.fg = 0x0; - root_window.bg = 0x55555500; + root_window.bg = 0x555555ff; root_window.ppsl = ppsl; root_window.parent = &root_window; root_window.size = (Point){hres, vres}; @@ -36,40 +42,90 @@ static void pixelRedGreenBlueReserved(Window *dst, Point p, RGBA32 col) { Window *parent; - // TODO: alpha - // TODO: this order is correct? - // UEFI-SPEC says that R is at the "byte zero". - uint32 _col = - (col & 0xff000000) >> 24 | // R - (col & 0x00ff0000) >> 8 | // G - (col & 0x0000ff00) << 8 | // B - (col & 0x000000ff) << 24; // A + uint32 r, g, b, or, og, ob, old_col, alpha; + + if (p.x < 0 || dst->size.x <= p.x || p.y < 0 || dst->size.y <= p.y) { + return; + } if ((parent = dst->parent) != dst) { pixel(parent, (Point) {p.x + dst->pos.x, p.y + dst->pos.y}, col); return; } - if (0 <= p.x && p.x < dst->size.x && 0 <= p.y && p.y < dst->size.y) { - dst->fb[p.y * dst->ppsl + p.x] = _col; - } + alpha = col & 0x000000ff; + r = (col & 0xff000000) >> 24; + g = (col & 0x00ff0000) >> 16; + b = (col & 0x0000ff00) >> 8; + old_col = dst->fb[p.y * dst->ppsl + p.x]; + or = (old_col & 0x000000ff); + og = (old_col & 0x0000ff00) >> 8; + ob = (old_col & 0x00ff0000) >> 16; + r = (or * (255-alpha) + r*alpha) / 255; + g = (og * (255-alpha) + g*alpha) / 255; + b = (ob * (255-alpha) + b*alpha) / 255; + dst->fb[p.y * dst->ppsl + p.x] = r | g << 8 | b << 16; } static void pixelBlueGreenRedReserved(Window *dst, Point p, RGBA32 col) { Window *parent; - // TODO: alpha - uint32 _col = - (col & 0xff000000) >> 8 | // R - (col & 0x00ff0000) >> 8 | // G - (col & 0x0000ff00) >> 8 | // B - (col & 0x000000ff) << 24; // A + uint32 r, g, b, or, og, ob, old_col, alpha; + + if (p.x < 0 || dst->size.x <= p.x || p.y < 0 || dst->size.y <= p.y) { + return; + } if ((parent = dst->parent) != dst) { pixel(parent, (Point) {p.x + dst->pos.x, p.y + dst->pos.y}, col); return; } - if (0 <= p.x && p.x < dst->size.x && 0 <= p.y && p.y < dst->size.y) { - dst->fb[p.y * dst->ppsl + p.x] = _col; + alpha = col & 0x000000ff; + r = (col & 0xff000000) >> 24; + g = (col & 0x00ff0000) >> 16; + b = (col & 0x0000ff00) >> 8; + old_col = dst->fb[p.y * dst->ppsl + p.x]; + or = (old_col & 0x00ff0000) >> 16; + og = (old_col & 0x0000ff00) >> 8; + ob = (old_col & 0x000000ff); + r = (or * (255-alpha) + r*alpha) / 255; + g = (og * (255-alpha) + g*alpha) / 255; + b = (ob * (255-alpha) + b*alpha) / 255; + dst->fb[p.y * dst->ppsl + p.x] = r << 16 | g << 8 | b; +} + +static RGBA32 +get_pixelRedGreenBlueReserved(Window *win, Point at) +{ + Window *parent; + uint32 col; + if (at.x < 0 || win->size.x <= at.x || at.y < 0 || win->size.y <= at.y) { + return 0; + } + if ((parent = win->parent) != win) { + return get_pixel(parent, (Point) {at.x + win->pos.x, at.y + win->pos.y}); + } + col = win->fb[at.y * win->ppsl + at.x]; + return 0x000000ff | // A + (col & 0x00ff0000) >> 8 | // B + (col & 0x0000ff00) << 8 | // G + (col & 0x000000ff) << 24 ; // R +} + +static RGBA32 +get_pixelBlueGreenRedReserved(Window *win, Point at) +{ + Window *parent; + uint32 col; + if (at.x < 0 || win->size.x <= at.x || at.y < 0 || win->size.y <= at.y) { + return 0; + } + if ((parent = win->parent) != win) { + return get_pixel(parent, (Point) {at.x + win->pos.x, at.y + win->pos.y}); } + col = win->fb[at.y * win->ppsl + at.x]; + return 0x000000ff | // A + (col & 0x00ff0000) << 8 | // R + (col & 0x0000ff00) << 8 | // G + (col & 0x000000ff) << 8 ; // B } void @@ -180,7 +236,32 @@ make_window(Window *parent, Window *child, Point pos, Point size, RGBA32 fg, RGB parent->nchildren++; clear(child); - border(parent, (Rectangle){pos, (Point){pos.x + size.x, pos.y + size.y}}, -4, 0x3f312b00); + border(parent, (Rectangle){pos, (Point){pos.x + size.x, pos.y + size.y}}, -4, 0x3f312bff); return 0; } + +void +draw_mouse(Window *dst, Mouse *mouse) +{ + int i, j; + for (i = 0; i < mouse->size.y; i++) { + for (j = 0; j < mouse->size.x; j++) { + mouse->hidden[j + i*mouse->size.x] = get_pixel(dst, (Point){mouse->pos.x + j, mouse->pos.y + i}); + pixel(dst, (Point){mouse->pos.x + j, mouse->pos.y + i}, + mouse->img[j + i*mouse->size.x]); + } + } +} + +void +clear_mouse(Window *dst, Mouse *mouse) +{ + int i, j; + for (i = 0; i < mouse->size.y; i++) { + for (j = 0; j < mouse->size.x; j++) { + pixel(dst, (Point){mouse->pos.x + j, mouse->pos.y + i}, + mouse->hidden[j + i*mouse->size.x]); + } + } +} +\ No newline at end of file diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c @@ -25,7 +25,7 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) root_window.children = root_children; Window win0; - make_window(&root_window, &win0, (Point){150, 100}, (Point){400, 300}, 0x0, 0xb9d08b00); + make_window(&root_window, &win0, (Point){150, 100}, (Point){400, 300}, 0x0, 0xb9d08bff); Console con0 = { .win = &win0, .font = &asciifont, @@ -33,7 +33,40 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) .h = 24, .pos = (Point){0, 0} }; + Point p = {0, 0}; + RGBA32 m_hidden[16*16], m_img[16*16] = { + 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0xffffffff, 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0xffffffff, 0x000000ff, 0x00000000, 0x00000000, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff, 0x000000ff, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + Mouse m = { + .size = (Point) {16, 16}, + .pos = (Point) {143, 150}, + .hidden = m_hidden, + .img = m_img, + }; + cons_printf(&con0, "hello world!\n"); + cons_printf(&con0, "pixel at {%d, %d}: %x\n", p.x, p.y, get_pixel(&root_window, p)); + for (;;) { + m.pos.x = (m.pos.x + 1) % root_window.size.x; + draw_mouse(&root_window, &m); + for (int i = 0; i < 0x100000; i++) { + } + clear_mouse(&root_window, &m); + } halt: for(;;) { __asm__("hlt"); } diff --git a/sys/src/kernel/start.s b/sys/src/kernel/start.s @@ -1,7 +0,0 @@ - .global kernel_start -kernel_start: - mov $(kernel_main_stack + 1024 * 1024), %rsp - call kernel_main -hlt: - hlt - jmp hlt