summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile13
-rw-r--r--src/boot/stage2_real_functions.asm2
-rw-r--r--src/gui/composite_widget.c137
-rw-r--r--src/gui/composite_widget.h32
-rw-r--r--src/gui/widget.c74
-rw-r--r--src/gui/widget.h19
6 files changed, 262 insertions, 15 deletions
diff --git a/src/Makefile b/src/Makefile
index 497a0d4..02ab439 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -11,16 +11,16 @@ all: image.bin kernel.sym
# truncate to correct number of sectors, we have
# 512 (boot, stage 1) + N * 512 (N currenty is 5, stage 2) for boot.bin
-# + M * 512 (M is currently 159) for kernel.bin
+# + M * 512 (M is currently 169) for kernel.bin
# (M + N + 1 is the number of sectors to be read in stage 2, as stage 1
# loads only the first sector, and stage 1 loads 5 sectors of stage 2,
-# adapt NOF_LOAD_SECTORS to 159)
+# adapt NOF_LOAD_SECTORS to 169)
# then we make sure the image has the size of a 1.44 MB floppy
# (emulators like qemu do some guess work for CHS resolution based
# on the size of the image)
image.bin: boot.bin kernel.bin magic.bin
cat boot.bin kernel.bin > image.tmp
- truncate -s 83968 image.tmp
+ truncate -s 89088 image.tmp
cat image.tmp magic.bin > image.bin
truncate -s 1474560 image.bin
@@ -33,7 +33,7 @@ kernel.bin: kernel.elf
kernel.sym: kernel.elf
$(OBJCOPY) --only-keep-debug kernel.elf kernel.sym
-kernel.elf: kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/mouse.o drivers/video/vga.o drivers/video/vga_font.o gui/widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o
+kernel.elf: kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.o kernel/serial.o hardware/port.o hardware/port_asm.o hardware/interrupts.o hardware/interrupts_asm.o hardware/pci.o drivers/driver.o drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/mouse.o drivers/video/vga.o drivers/video/vga_font.o gui/widget.o gui/composite_widget.o libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o
$(LD) -o kernel.elf -N -n -Ttext 0x8800 --oformat elf32-i386 \
kernel/kernel.o kernel/kernel_asm.o \
kernel/console.o kernel/vgatext.o kernel/serial.o \
@@ -44,7 +44,7 @@ kernel.elf: kernel/kernel.o kernel/kernel_asm.o kernel/console.o kernel/vgatext.
drivers/hdi/ps2/keyboard.o drivers/hdi/ps2/mouse.o \
drivers/video/vga.o drivers/video/vga_font.o \
libc/string.o libc/stdlib.o libc/stdio.o libc/setjmp.o \
- gui/widget.o
+ gui/widget.o gui/composite_widget.o
magic.bin: boot/magic.asm
$(NASM) boot/magic.asm -DMAGIC='"$(MAGIC)"' -f bin -o magic.bin
@@ -106,6 +106,9 @@ libc/setjmp.o: libc/setjmp.asm
gui/widget.o: gui/widget.c gui/widget.h
$(CC) $(CFLAGS) -c -o gui/widget.o gui/widget.c
+gui/composite_widget.o: gui/composite_widget.c gui/composite_widget.h
+ $(CC) $(CFLAGS) -c -o gui/composite_widget.o gui/composite_widget.c
+
clean:
-rm -f boot.bin kernel.bin kernel.sym kernel.elf image.bin magic.bin boot.map image.tmp \
serial.log \
diff --git a/src/boot/stage2_real_functions.asm b/src/boot/stage2_real_functions.asm
index cc2ad26..61aa81e 100644
--- a/src/boot/stage2_real_functions.asm
+++ b/src/boot/stage2_real_functions.asm
@@ -2,7 +2,7 @@
; (note: the first sector gets loaded by the BIOS, the
; next 5 sectors are read by the simple stage 1 loader,
; so subtract 6 here!)
-NOF_LOAD_SECTORS equ 159
+NOF_LOAD_SECTORS equ 169
; data sections used for reading the kernel from disk
SECTORS_PER_CYLINDER:
diff --git a/src/gui/composite_widget.c b/src/gui/composite_widget.c
new file mode 100644
index 0000000..e9cc166
--- /dev/null
+++ b/src/gui/composite_widget.c
@@ -0,0 +1,137 @@
+#include "composite_widget.h"
+
+#include "string.h"
+#include "stddef.h"
+
+static composite_widget_vtable_t composite_widget_vtable = {
+ {
+ composite_widget_draw,
+ composite_widget_get_focus,
+ widget_model_to_screen,
+ widget_contains_coordinate,
+ composite_widget_on_mouse_down,
+ composite_widget_on_mouse_up,
+ composite_widget_on_mouse_move,
+ composite_widget_on_key_down,
+ composite_widget_on_key_up
+ },
+ composite_widget_add_child
+};
+
+void composite_widget_init( composite_widget_t *widget, widget_t *parent, const int x, const int y, const int w, const int h )
+{
+ memset( widget, 0, sizeof( composite_widget_t ) );
+
+ widget_init( &widget->base, parent, x, y, w, h );
+
+ widget->nof_children = 0;
+ widget->focused_child = NULL;
+ memset( widget->children, 0, MAX_NOF_WIDGET_CHILDREN * sizeof( widget_t * ) );
+
+ widget->vtable = &composite_widget_vtable;
+}
+
+void composite_widget_draw( void *obj, graphics_context_t *context )
+{
+ composite_widget_t *widget = obj;
+
+ widget->base.vtable->draw( obj, context );
+
+ for( int i = widget->nof_children - 1; i >= 0; i-- ) {
+ widget_t *child = widget->children[i];
+ child->vtable->draw( child, context );
+ }
+}
+
+void composite_widget_get_focus( void *obj, widget_t *widget )
+{
+ composite_widget_t *o = obj;
+
+ o->focused_child = widget;
+
+ o->base.vtable->get_focus( o, widget );
+}
+
+void composite_widget_add_child( void *obj, widget_t *child )
+{
+ composite_widget_t *widget = obj;
+
+ if( widget->nof_children >= MAX_NOF_WIDGET_CHILDREN ) {
+ // TODO: kernel_panic, but in an indirect way because
+ // the GUI framework should not depend on the kernel.
+ // Maybe something like a runtime context similar to
+ // the graphics context?
+ return;
+ }
+
+ widget->children[widget->nof_children++] = child;
+}
+
+void composite_widget_on_mouse_down( void *obj, const int x, const int y )
+{
+ composite_widget_t *widget = obj;
+
+ for( int i = 0; i < widget->nof_children; i++ ) {
+ widget_t *child = widget->children[i];
+ if( child->vtable->contains_coordinate( child, x - widget->base.x, y - widget->base.y ) ) {
+ child->vtable->on_mouse_down( child, x - widget->base.x, y - widget->base.y );
+ break;
+ }
+ }
+}
+
+void composite_widget_on_mouse_up( void *obj, const int x, const int y )
+{
+ composite_widget_t *widget = obj;
+
+ for( int i = 0; i < widget->nof_children; i++ ) {
+ widget_t *child = widget->children[i];
+ if( child->vtable->contains_coordinate( child, x - widget->base.x, y - widget->base.y ) ) {
+ child->vtable->on_mouse_up( child, x - widget->base.x, y - widget->base.y );
+ break;
+ }
+ }
+}
+
+void composite_widget_on_mouse_move( void *obj, const int old_x, const int old_y, const int x, const int y )
+{
+ composite_widget_t *widget = obj;
+ widget_t *moved_out_from = NULL;
+
+ for( int i = 0; i < widget->nof_children; i++ ) {
+ widget_t *child = widget->children[i];
+ if( child->vtable->contains_coordinate( child, old_x - widget->base.x, old_y - widget->base.y ) ) {
+ child->vtable->on_mouse_move( child, old_x - widget->base.x, old_y - widget->base.y, x - widget->base.x, y - widget->base.y );
+ moved_out_from = child;
+ break;
+ }
+ }
+
+ for( int i = 0; i < widget->nof_children; i++ ) {
+ widget_t *child = widget->children[i];
+ if( child->vtable->contains_coordinate( child, x - widget->base.x, y - widget->base.y ) ) {
+ if( moved_out_from != NULL ) {
+ child->vtable->on_mouse_move( child, old_x - widget->base.x, old_y - widget->base.y, x - widget->base.x, y - widget->base.y );
+ break;
+ }
+ }
+ }
+}
+
+void composite_widget_on_key_down( void *obj, char c )
+{
+ composite_widget_t *widget = obj;
+
+ if( widget->focused_child != NULL ) {
+ widget->focused_child->vtable->on_key_down( widget->focused_child, c );
+ }
+}
+
+void composite_widget_on_key_up( void *obj, char c )
+{
+ composite_widget_t *widget = obj;
+
+ if( widget->focused_child != NULL ) {
+ widget->focused_child->vtable->on_key_up( widget->focused_child, c );
+ }
+}
diff --git a/src/gui/composite_widget.h b/src/gui/composite_widget.h
new file mode 100644
index 0000000..d3ba90a
--- /dev/null
+++ b/src/gui/composite_widget.h
@@ -0,0 +1,32 @@
+#ifndef COMPOSITE_WIDGET_H
+#define COMPOSITE_WIDGET_H
+
+#include "widget.h"
+
+#define MAX_NOF_WIDGET_CHILDREN 100
+
+typedef struct {
+ widget_vtable_t base;
+ void (*add_child)( void *obj, widget_t *child );
+} composite_widget_vtable_t;
+
+typedef struct {
+ widget_t base;
+ composite_widget_vtable_t *vtable;
+ widget_t *children[MAX_NOF_WIDGET_CHILDREN];
+ int nof_children;
+ widget_t *focused_child;
+} composite_widget_t;
+
+void composite_widget_init( composite_widget_t *widget, widget_t *parent, const int x, const int y, const int w, const int h );
+
+void composite_widget_draw( void *obj, graphics_context_t *context );
+void composite_widget_get_focus( void *obj, widget_t *widget );
+void composite_widget_on_mouse_down( void *obj, const int x, const int y );
+void composite_widget_on_mouse_up( void *obj, const int x, const int y );
+void composite_widget_on_mouse_move( void *obj, const int old_x, const int old_y, const int x, const int y );
+void composite_widget_on_key_down( void *obj, char c );
+void composite_widget_on_key_up( void *obj, char c );
+void composite_widget_add_child( void *obj, widget_t *child );
+
+#endif // COMPOSITE_WIDGET_H
diff --git a/src/gui/widget.c b/src/gui/widget.c
index 313fd49..cd77d03 100644
--- a/src/gui/widget.c
+++ b/src/gui/widget.c
@@ -5,12 +5,14 @@
static widget_vtable_t widget_vtable = {
widget_draw,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
+ widget_get_focus,
+ widget_model_to_screen,
+ widget_contains_coordinate,
+ widget_on_mouse_down,
+ widget_on_mouse_up,
+ widget_on_mouse_move,
+ widget_on_key_down,
+ widget_on_key_up
};
void widget_init( widget_t *widget, widget_t *parent, const int x, const int y, const int w, const int h )
@@ -29,7 +31,65 @@ void widget_init( widget_t *widget, widget_t *parent, const int x, const int y,
void widget_draw( void *obj, graphics_context_t *context )
{
widget_t *widget = obj;
+ int x = 0;
+ int y = 0;
- vga_draw_rectangle( context, widget->x, widget->y, widget->w, widget->h,
+ widget->vtable->model_to_screen( widget, &x, &y );
+
+ vga_draw_rectangle( context, x, y, widget->w, widget->h,
vga_make_RGB( 0xFF, 0xFF, 0xFF ) );
}
+
+void widget_get_focus( void *obj, widget_t *widget )
+{
+ widget_t *o = obj;
+
+ if( o->parent != NULL ) {
+ o->parent->vtable->get_focus( widget->parent, widget );
+ }
+}
+
+void widget_model_to_screen( void *obj, int *x, int *y )
+{
+ widget_t *widget = obj;
+
+ if( widget->parent != NULL ) {
+ widget->parent->vtable->model_to_screen( widget->parent, x, y );
+ }
+
+ *x += widget->x;
+ *y += widget->y;
+}
+
+bool widget_contains_coordinate( void *obj, const int x, const int y )
+{
+ widget_t *widget = obj;
+
+ return widget->x <= x && x < widget->x + widget->w &&
+ widget->y <= y && y < widget->y + widget->h;
+}
+
+void widget_on_mouse_down( void *obj, const int x, const int y )
+{
+ widget_t *widget = obj;
+
+ if( widget->focusable ) {
+ widget->vtable->get_focus( widget, widget );
+ }
+}
+
+void widget_on_mouse_up( void *obj, const int x, const int y )
+{
+}
+
+void widget_on_mouse_move( void *obj, const int old_x, const int old_y, const int x, const int y )
+{
+}
+
+void widget_on_key_down( void *obj, char c )
+{
+}
+
+void widget_on_key_up( void *obj, char c )
+{
+}
diff --git a/src/gui/widget.h b/src/gui/widget.h
index a1e9a21..1fd23ac 100644
--- a/src/gui/widget.h
+++ b/src/gui/widget.h
@@ -3,14 +3,20 @@
#include "graphics_context.h"
+#include <stdbool.h>
+
+struct widget_t;
+
typedef struct {
void (*draw)( void *obj, graphics_context_t *context );
- void (*get_focus)( void *obj );
- void (*widget_model_to_screen)( void *obj, int *x, int *y );
+ void (*get_focus)( void *obj, struct widget_t *widget );
+ void (*model_to_screen)( void *obj, int *x, int *y );
+ bool (*contains_coordinate)( void *obj, const int x, const int y );
void (*on_mouse_down)( void *obj, const int x, const int y );
void (*on_mouse_up)( void *obj, const int x, const int y );
void (*on_mouse_move)( void *obj, const int old_x, const int old_y, const int x, const int y );
void (*on_key_down)( void *obj, char c );
+ void (*on_key_up)( void *obj, char c );
} widget_vtable_t;
typedef struct widget_t {
@@ -18,6 +24,7 @@ typedef struct widget_t {
int y;
int w;
int h;
+ bool focusable;
struct widget_t *parent;
widget_vtable_t *vtable;
} widget_t;
@@ -25,5 +32,13 @@ typedef struct widget_t {
void widget_init( widget_t *widget, widget_t *parent, const int x, const int y, const int w, const int h );
void widget_draw( void *obj, graphics_context_t *context );
+void widget_get_focus( void *obj, widget_t *widget );
+void widget_model_to_screen( void *obj, int *x, int *y );
+bool widget_contains_coordinate( void *obj, const int x, const int y );
+void widget_on_mouse_down( void *obj, const int x, const int y );
+void widget_on_mouse_up( void *obj, const int x, const int y );
+void widget_on_mouse_move( void *obj, const int old_x, const int old_y, const int x, const int y );
+void widget_on_key_down( void *obj, char c );
+void widget_on_key_up( void *obj, char c );
#endif // WIDGET_H