From df9e7eb31157924e0fad5baa5da08ba27d70c2ed Mon Sep 17 00:00:00 2001 From: Ry Date: Wed, 12 Jul 2023 00:00:08 -0700 Subject: [PATCH] Fetcher: Initial commit This commit includes needed kernel changes and additions. --- Makefile | 11 +++ applications/fetcher/Browser.okm | 43 ++++++++++ applications/fetcher/Desktop.okm | 112 +++++++++++++++++++++++++++ applications/fetcher/Fetcher.okm | 20 +++++ applications/fetcher/OS.okm | 25 ++++++ applications/fetcher/start.asm | 38 +++++++++ base_image/startup.cfg.default | 1 + fox32os.def | 6 ++ kernel/main.asm | 8 ++ kernel/task.asm | 2 +- kernel/widget/button.asm | 11 ++- kernel/widget/widget.asm | 19 ++++- kernel/window/event_manager_task.asm | 51 ++++++++---- kernel/window/messagebox.asm | 2 +- kernel/window/window.asm | 77 +++++++++++++++++- meta/okameron | 2 +- 16 files changed, 405 insertions(+), 23 deletions(-) create mode 100644 applications/fetcher/Browser.okm create mode 100644 applications/fetcher/Desktop.okm create mode 100644 applications/fetcher/Fetcher.okm create mode 100644 applications/fetcher/OS.okm create mode 100644 applications/fetcher/start.asm diff --git a/Makefile b/Makefile index a30dec5..538588c 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,15 @@ base_image/barclock.fxf: applications/barclock/main.asm base_image/terminal.fxf: applications/terminal/main.asm $(wildcard applications/terminal/*.asm) $(FOX32ASM) $< $@ +base_image/fetcher.fxf: applications/fetcher/Fetcher.okm $(wildcard applications/fetcher/*.okm) + lua $(OKAMERON) -arch=fox32 -startup=applications/fetcher/start.asm $< \ + applications/fetcher/Browser.okm \ + applications/fetcher/Desktop.okm \ + applications/fetcher/OS.okm \ + > applications/fetcher/fetcher.asm + $(FOX32ASM) applications/fetcher/fetcher.asm $@ + rm applications/fetcher/fetcher.asm + base_image/serial.fxf: applications/serial/main.asm $(wildcard applications/terminal/*.asm) $(FOX32ASM) $< $@ @@ -62,6 +71,7 @@ FILES = \ base_image/sh.fxf \ base_image/barclock.fxf \ base_image/terminal.fxf \ + base_image/fetcher.fxf \ base_image/serial.fxf \ base_image/foxpaint.fxf \ base_image/okmpaint.fxf \ @@ -75,6 +85,7 @@ ROM_FILES = \ base_image/sh.fxf \ base_image/barclock.fxf \ base_image/terminal.fxf \ + base_image/fetcher.fxf \ base_image/serial.fxf \ base_image/bg.fxf \ base_image/launcher.fxf diff --git a/applications/fetcher/Browser.okm b/applications/fetcher/Browser.okm new file mode 100644 index 0000000..2d219e2 --- /dev/null +++ b/applications/fetcher/Browser.okm @@ -0,0 +1,43 @@ +MODULE Browser; + IMPORT OS; + + VAR browserRunning: CHAR; + browserWindow: ARRAY 36 OF CHAR; + browserIcons: ARRAY 31 OF Fox32OSButtonWidget; + + PROCEDURE BrowserMain(diskId: INT;); + BEGIN + browserRunning := 1; + + (* create the window and fill it with white *) + new_window(PTROF(browserWindow), "Fetcher", 384, 192, 64, 64, 0, PTROF(browserIcons)); + fill_window(0FFFFFFFFH, PTROF(browserWindow)); + (*draw_widgets_to_window(PTROF(browserWindow));*) + + WHILE browserRunning DO + GetNextWindowEvent(PTROF(browserWindow)); + + (* mouse click event *) + IF eventArgs[0] = PTROF(EVENT_TYPE_MOUSE_CLICK) THEN + IF (eventArgs[1] <| 8) & (eventArgs[2] <| 16) THEN + destroy_window(PTROF(browserWindow)); + browserRunning := 0; + ELSIF eventArgs[2] <| 16 THEN + start_dragging_window(PTROF(browserWindow)); + END; + handle_widget_click(PTROF(browserWindow), eventArgs[1], eventArgs[2]); + + (* mouse click event *) + ELSIF eventArgs[0] = PTROF(EVENT_TYPE_BUTTON_CLICK) THEN + HandleIconClick(eventArgs[1]); + END; + + save_state_and_yield_task(); + END; + END; + + PROCEDURE HandleIconClick(buttonId: INT;); + BEGIN + (* TODO *) + END; +END. diff --git a/applications/fetcher/Desktop.okm b/applications/fetcher/Desktop.okm new file mode 100644 index 0000000..f0699f7 --- /dev/null +++ b/applications/fetcher/Desktop.okm @@ -0,0 +1,112 @@ +MODULE Desktop; + IMPORT OS; + + VAR desktopRunning: CHAR; + desktopWindow: ARRAY 36 OF CHAR; + desktopIcons: ARRAY 5 OF Fox32OSButtonWidget; + + PROCEDURE DesktopMain(); + BEGIN + desktopRunning := 1; + + (* set up the desktop icon widgets *) + SetupDesktopIconStructs(); + + (* create the window and make it fully transparent, draw the button widgets to it, and mark it as "always background *) + new_window(PTROF(desktopWindow), "Desktop", 640, 448, 0, 16, 0, PTROF(desktopIcons)); + fill_overlay(000000000H, get_window_overlay_number(PTROF(desktopWindow))); + draw_widgets_to_window(PTROF(desktopWindow)); + set_window_flags(000000001H, PTROF(desktopWindow)); + + WHILE desktopRunning DO + GetNextWindowEvent(PTROF(desktopWindow)); + + (* mouse click event *) + IF eventArgs[0] = PTROF(EVENT_TYPE_MOUSE_CLICK) THEN + handle_widget_click(PTROF(desktopWindow), eventArgs[1], eventArgs[2]); + + (* mouse click event *) + ELSIF eventArgs[0] = PTROF(EVENT_TYPE_BUTTON_CLICK) THEN + HandleDesktopIconClick(eventArgs[1]); + END; + + save_state_and_yield_task(); + END; + END; + + PROCEDURE HandleDesktopIconClick(buttonId: INT;); + BEGIN + IF launch_fxf_from_disk("fetcher.fxf", get_boot_disk_id(), 0FFFFFFFFH, buttonId, 0, 0, 0) = 0FFFFFFFFH THEN + new_messagebox("Failed to start new", "instance of fetcher.fxf", 0, 64, 64, 200); + END; + END; + + PROCEDURE SetupDesktopIconStructs(); + VAR desktopIcon: POINTER TO Fox32OSButtonWidget; + prevDesktopIcon: POINTER TO Fox32OSButtonWidget; + BEGIN + desktopIcon := PTROF(desktopIcons[0]); + desktopIcon^.type := WIDGET_TYPE_BUTTON; + desktopIcon^.next := PTROF(desktopIcons[1]); + desktopIcon^.id := 0; + desktopIcon^.text := "Disk 0"; + desktopIcon^.fgColor := 0FF000000H; + desktopIcon^.bgColor := 0FFFFFFFFH; + desktopIcon^.width := 32; + desktopIcon^.height := 32 + 16; + desktopIcon^.x := 592; + desktopIcon^.y := 16; + + prevDesktopIcon := desktopIcon; + desktopIcon := PTROF(desktopIcons[1]); + desktopIcon^.type := WIDGET_TYPE_BUTTON; + desktopIcon^.next := PTROF(desktopIcons[2]); + desktopIcon^.id := 1; + desktopIcon^.text := "Disk 1"; + desktopIcon^.fgColor := 0FF000000H; + desktopIcon^.bgColor := 0FFFFFFFFH; + desktopIcon^.width := 32; + desktopIcon^.height := 32 + 16; + desktopIcon^.x := 592; + desktopIcon^.y := prevDesktopIcon^.y + 32 + 32; + + prevDesktopIcon := desktopIcon; + desktopIcon := PTROF(desktopIcons[2]); + desktopIcon^.type := WIDGET_TYPE_BUTTON; + desktopIcon^.next := PTROF(desktopIcons[3]); + desktopIcon^.id := 1; + desktopIcon^.text := "Disk 2"; + desktopIcon^.fgColor := 0FF000000H; + desktopIcon^.bgColor := 0FFFFFFFFH; + desktopIcon^.width := 32; + desktopIcon^.height := 32 + 16; + desktopIcon^.x := 592; + desktopIcon^.y := prevDesktopIcon^.y + 32 + 32; + + prevDesktopIcon := desktopIcon; + desktopIcon := PTROF(desktopIcons[3]); + desktopIcon^.type := WIDGET_TYPE_BUTTON; + desktopIcon^.next := PTROF(desktopIcons[4]); + desktopIcon^.id := 1; + desktopIcon^.text := "Disk 3"; + desktopIcon^.fgColor := 0FF000000H; + desktopIcon^.bgColor := 0FFFFFFFFH; + desktopIcon^.width := 32; + desktopIcon^.height := 32 + 16; + desktopIcon^.x := 592; + desktopIcon^.y := prevDesktopIcon^.y + 32 + 32; + + prevDesktopIcon := desktopIcon; + desktopIcon := PTROF(desktopIcons[4]); + desktopIcon^.type := WIDGET_TYPE_BUTTON; + desktopIcon^.next := 0; + desktopIcon^.id := 1; + desktopIcon^.text := "Disk 4"; + desktopIcon^.fgColor := 0FF000000H; + desktopIcon^.bgColor := 0FFFFFFFFH; + desktopIcon^.width := 32; + desktopIcon^.height := 32 + 16; + desktopIcon^.x := 592; + desktopIcon^.y := prevDesktopIcon^.y + 32 + 32; + END; +END. diff --git a/applications/fetcher/Fetcher.okm b/applications/fetcher/Fetcher.okm new file mode 100644 index 0000000..f4646ce --- /dev/null +++ b/applications/fetcher/Fetcher.okm @@ -0,0 +1,20 @@ +MODULE Fetcher; + IMPORT OS, Browser, Desktop; + + EXTERN terminalStreamPtr: POINTER TO CHAR; + EXTERN arg0Ptr: POINTER TO CHAR; + + PROCEDURE Main(); + BEGIN + IF (terminalStreamPtr = 0) & (arg0Ptr = 0) THEN + (* probably launched from startup.cfg *) + DesktopMain(); + ELSIF arg0Ptr <|= 5 THEN + (* launched from an existing instance of fetcher *) + BrowserMain(arg0Ptr); + ELSE + (* probably launched from the terminal *) + BrowserMain(string_to_int(arg0Ptr, 10)); + END; + END; +END. diff --git a/applications/fetcher/OS.okm b/applications/fetcher/OS.okm new file mode 100644 index 0000000..46d6eb8 --- /dev/null +++ b/applications/fetcher/OS.okm @@ -0,0 +1,25 @@ +MODULE OS; + EXTERN PROCEDURE new_window, destroy_window, draw_str_to_overlay, get_window_overlay_number, + draw_widgets_to_window, draw_filled_rectangle_to_overlay, GetNextWindowEvent, DrawPixel, + save_state_and_yield_task, start_dragging_window, handle_widget_click, fill_window, fill_overlay, + set_window_flags, menu_update_event, menu_bar_click_event, close_menu, new_messagebox, + launch_fxf_from_disk, get_boot_disk_id, string_to_int: INT; + + EXTERN PROCEDURE brk: INT; + + EXTERN EVENT_TYPE_MOUSE_CLICK, + EVENT_TYPE_MOUSE_RELEASE, + EVENT_TYPE_BUTTON_CLICK, + EVENT_TYPE_MENU_BAR_CLICK, + EVENT_TYPE_MENU_UPDATE, + EVENT_TYPE_MENU_CLICK, + EVENT_TYPE_MENU_ACK, + WIDGET_TYPE_BUTTON: INT; + + EXTERN eventArgs: ARRAY 8 OF INT; + + TYPE Fox32OSButtonWidget = RECORD + next, id, type, text, fgColor, bgColor: INT; + width, height, x, y: SHORT; + END; +END. diff --git a/applications/fetcher/start.asm b/applications/fetcher/start.asm new file mode 100644 index 0000000..1a09207 --- /dev/null +++ b/applications/fetcher/start.asm @@ -0,0 +1,38 @@ + pop [terminalStreamPtr] + pop [arg0Ptr] + + call Main + call end_current_task + +GetNextWindowEvent: + push r8 + call get_next_window_event + mov r8, eventArgs + mov [r8], r0 + add r8, 4 + mov [r8], r1 + add r8, 4 + mov [r8], r2 + add r8, 4 + mov [r8], r3 + add r8, 4 + mov [r8], r4 + add r8, 4 + mov [r8], r5 + add r8, 4 + mov [r8], r6 + add r8, 4 + mov [r8], r7 + pop r8 + ret + +brk: + brk + ret + +eventArgs: data.fill 0, 32 +terminalStreamPtr: data.32 0 +arg0Ptr: data.32 0 + + #include "../../../fox32rom/fox32rom.def" + #include "../../fox32os.def" diff --git a/base_image/startup.cfg.default b/base_image/startup.cfg.default index d4c3fa2..0d5d571 100644 --- a/base_image/startup.cfg.default +++ b/base_image/startup.cfg.default @@ -1,4 +1,5 @@ bg fxf barclockfxf +fetcher fxf launcherfxf terminalfxf diff --git a/fox32os.def b/fox32os.def index 40676b1..1df5b2b 100644 --- a/fox32os.def +++ b/fox32os.def @@ -5,10 +5,12 @@ get_os_version: jmp [0x00000810] get_os_api_version: jmp [0x00000814] get_current_disk_id: jmp [0x00000818] set_current_disk_id: jmp [0x0000081C] +get_boot_disk_id: jmp [0x00000820] ; FXF jump table parse_fxf_binary: jmp [0x00000910] launch_fxf_from_disk: jmp [0x00000914] +launch_fxf_from_open_file: jmp [0x00000918] ; task jump table new_task: jmp [0x00000A10] @@ -35,6 +37,7 @@ get_window_overlay_number: jmp [0x00000C2C] start_dragging_window: jmp [0x00000C30] new_messagebox: jmp [0x00000C34] get_active_window_struct: jmp [0x00000C38] +set_window_flags: jmp [0x00000C3C] ; VFS jump table open: jmp [0x00000D10] @@ -53,3 +56,6 @@ const EVENT_TYPE_BUTTON_CLICK: 0x80000000 ; widget types const WIDGET_TYPE_BUTTON: 0x00000000 + +; window flags +const WINDOW_FLAG_ALWAYS_BACKGROUND: 1 diff --git a/kernel/main.asm b/kernel/main.asm index b2b8cee..94a4737 100644 --- a/kernel/main.asm +++ b/kernel/main.asm @@ -23,6 +23,7 @@ jump_table: data.32 get_os_api_version data.32 get_current_disk_id data.32 set_current_disk_id + data.32 get_boot_disk_id ; FXF jump table org.pad 0x00000110 @@ -58,6 +59,7 @@ jump_table: data.32 start_dragging_window data.32 new_messagebox data.32 get_active_window_struct + data.32 set_window_flags ; VFS jump table org.pad 0x00000510 @@ -101,6 +103,7 @@ entry_ok: mov rsp, SYSTEM_STACK ; save the boot disk id that the bootloader passed in r0 + mov.8 [boot_disk_id], r0 mov.8 [current_disk_id], r0 ; clear the background @@ -344,6 +347,10 @@ api_version_too_low_error: call draw_format_str_to_background rjmp 0 +get_boot_disk_id: + movz.8 r0, [boot_disk_id] + ret + get_current_disk_id: movz.8 r0, [current_disk_id] ret @@ -415,6 +422,7 @@ bottom_bar_patterns: next_task: data.8 0 current_disk_id: data.8 0 +boot_disk_id: data.8 0 startup_cfg: data.str "startup cfg" startup_cfg_struct: data.fill 0, 32 startup_file: data.str " " diff --git a/kernel/task.asm b/kernel/task.asm index 956ec77..378b8fa 100644 --- a/kernel/task.asm +++ b/kernel/task.asm @@ -24,7 +24,7 @@ new_task: call task_store mov [task_queue_ptr], r0 - ; fall-through + jmp save_state_and_yield_task ; switch to the next task in the queue ; no registers are saved upon task yield diff --git a/kernel/widget/button.asm b/kernel/widget/button.asm index ffdf900..afdb1bd 100644 --- a/kernel/widget/button.asm +++ b/kernel/widget/button.asm @@ -8,7 +8,7 @@ ; data.32 foreground_color - text foreground color ; data.32 background_color - button background color ; data.16 width - width of this button -; data.16 reserved +; data.16 height - height of this button ; data.16 x_pos - X coordinate of this widget ; data.16 y_pos - Y coordinate of this widget @@ -24,6 +24,7 @@ const BUTTON_WIDGET_STRUCT_SIZE: 32 ; 8 words = 32 bytes ; r4: button width ; r5: X coordinate ; r6: Y coordinate +; r7: button height draw_button_widget: push r0 push r1 @@ -31,6 +32,7 @@ draw_button_widget: push r3 push r4 push r5 + push r7 push r10 push r20 push r30 @@ -64,7 +66,9 @@ draw_button_widget_strlen_loop: mov r5, r0 mov r2, r31 mov r4, r3 - mov r3, 16 + cmp r7, 16 + iflt mov r7, 16 + mov r3, r7 mov r0, r30 mov r1, r6 call draw_filled_rectangle_to_overlay @@ -79,6 +83,8 @@ draw_button_widget_strlen_loop: mov r3, r2 mov r1, r5 mov r2, r6 + add r2, r7 + sub r2, 16 mov r5, r10 call draw_str_to_overlay @@ -86,6 +92,7 @@ draw_button_widget_strlen_loop: pop r30 pop r20 pop r10 + pop r7 pop r5 pop r4 pop r3 diff --git a/kernel/widget/widget.asm b/kernel/widget/widget.asm index 5b2418c..7f0aedc 100644 --- a/kernel/widget/widget.asm +++ b/kernel/widget/widget.asm @@ -43,6 +43,7 @@ draw_widgets_to_window_button: push r4 push r5 push r6 + push r7 push r10 ; put button parameters in registers for the drawing routine @@ -54,13 +55,16 @@ draw_widgets_to_window_button: mov r3, [r10] ; background_color add r10, 4 movz.16 r4, [r10] ; width - add r10, 4 + add r10, 2 + movz.16 r7, [r10] ; height + add r10, 2 movz.16 r5, [r10] ; x_pos add r10, 2 movz.16 r6, [r10] ; y_pos call draw_button_widget pop r10 + pop r7 pop r6 pop r5 pop r4 @@ -115,6 +119,7 @@ handle_widget_click_button: push r10 push r11 push r12 + push r13 push r21 push r22 @@ -122,8 +127,14 @@ handle_widget_click_button: add r0, 16 movz.16 r10, [r0] + ; get button height + add r0, 2 + movz.16 r13, [r0] + cmp r13, 16 + iflt mov r13, 16 + ; get button X coordinate - add r0, 4 + add r0, 2 movz.16 r11, [r0] ; get button Y coordinate @@ -136,7 +147,7 @@ handle_widget_click_button: ; calculate button's bottom right corner coordinate mov r22, r12 - add r22, 16 + add r22, r13 ; check if r1 is between r11 and r21 ; and if r2 is between r12 and r22 @@ -152,6 +163,7 @@ handle_widget_click_button: ; if we reach this point then the button was clicked!! pop r22 pop r21 + pop r13 pop r12 pop r11 pop r10 @@ -174,6 +186,7 @@ handle_widget_click_button: handle_widget_click_button_no_click: pop r22 pop r21 + pop r13 pop r12 pop r11 pop r10 diff --git a/kernel/window/event_manager_task.asm b/kernel/window/event_manager_task.asm index 3a48311..76370de 100644 --- a/kernel/window/event_manager_task.asm +++ b/kernel/window/event_manager_task.asm @@ -27,6 +27,12 @@ start_event_manager_task: event_manager_task_loop: call get_next_event + ; mouse + cmp r0, EVENT_TYPE_MOUSE_CLICK + ifz call event_manager_task_mouse_event + cmp r0, EVENT_TYPE_MOUSE_RELEASE + ifz call event_manager_task_mouse_event + cmp.8 [active_window_offset], 0xFF ifz rjmp event_manager_task_loop_end @@ -40,12 +46,6 @@ event_manager_task_loop: cmp r0, EVENT_TYPE_MENU_UPDATE ifz call add_event_to_active_window - ; mouse - cmp r0, EVENT_TYPE_MOUSE_CLICK - ifz call event_manager_task_mouse_event - cmp r0, EVENT_TYPE_MOUSE_RELEASE - ifz call event_manager_task_mouse_event - ; keyboard cmp r0, EVENT_TYPE_KEY_DOWN ifz call add_event_to_active_window @@ -85,6 +85,9 @@ event_manager_task_mouse_event: ; get the overlay number of the active window movz.8 r0, [active_window_offset] + cmp.8 r0, 0xFF + ifz pop r1 + ifz jmp event_manager_task_mouse_event_inactive_window_was_clicked call window_list_offset_to_struct call get_window_overlay_number @@ -114,19 +117,30 @@ event_manager_task_mouse_event_inactive_window_was_clicked: call get_window_with_overlay mov r1, r2 - ; give up if a window was not found for this overlay - cmp r0, 0x00000000 - ifz pop r2 - ifz pop r1 - ifz pop r0 - ifz ret + ; r0: currently active window struct + ; r1: clicked window struct + + ; give up if a window was not found for the clicked overlay cmp r1, 0x00000000 ifz pop r2 ifz pop r1 ifz pop r0 ifz ret - ; swap the two + ; if there is no active window, but we reached this point, + ; then assume the click was on an inactive window marked as "always background" + ; it's probably bad to assume this, more checks would be good + cmp r0, 0x00000000 + ifz jmp event_manager_task_mouse_event_inactive_window_was_clicked_no_change + + ; swap the two, if the "always background" flag is not set for the clicked window + push r1 + add r1, 25 + movz.16 r1, [r1] + and r1, WINDOW_FLAG_ALWAYS_BACKGROUND + cmp r1, 0 + pop r1 + ifnz jmp event_manager_task_mouse_event_inactive_window_was_clicked_no_change call swap_windows ; mark the clicked window as the active window @@ -146,4 +160,15 @@ event_manager_task_mouse_event_inactive_window_was_clicked: pop r2 pop r1 pop r0 + call add_mouse_event_to_active_window ret +event_manager_task_mouse_event_inactive_window_was_clicked_no_change: + mov [old_r8], r8 + mov r8, r1 + pop r2 + pop r1 + pop r0 + call add_mouse_event_to_inactive_window + mov r8, [old_r8] + ret +old_r8: data.32 0 diff --git a/kernel/window/messagebox.asm b/kernel/window/messagebox.asm index f786546..4b2f7c3 100644 --- a/kernel/window/messagebox.asm +++ b/kernel/window/messagebox.asm @@ -81,7 +81,7 @@ messagebox_event_loop: cmp r0, EVENT_TYPE_BUTTON_CLICK ifz jmp messagebox_ok_clicked - call yield_task + call save_state_and_yield_task jmp messagebox_event_loop messagebox_ok_clicked: diff --git a/kernel/window/window.asm b/kernel/window/window.asm index 1b3a235..5f78eae 100644 --- a/kernel/window/window.asm +++ b/kernel/window/window.asm @@ -11,7 +11,7 @@ ; data.16 y_pos - Y coordinate of this window (top left corner of title bar) ; data.8 overlay - overlay number of this window ; data.8 reserved_1 -; data.16 reserved_2 +; data.16 flags - flags for this window ; data.32 menu_bar_ptr - pointer to this window's menu bar root struct, or 0 for none ; data.32 first_widget_ptr - pointer to this window's first widget @@ -19,6 +19,7 @@ const WINDOW_STRUCT_SIZE: 36 ; 9 words = 36 bytes const TITLE_BAR_HEIGHT: 16 const TITLE_BAR_TEXT_FOREGROUND: 0xFF000000 const TITLE_BAR_TEXT_BACKGROUND: 0xFFFFFFFF +const WINDOW_FLAG_ALWAYS_BACKGROUND: 1 ; create a new window and allocate memory as required ; inputs: @@ -218,6 +219,21 @@ destroy_window_no_more_windows: pop r0 ret +; call this if the user clicks on a window's title bar +; inputs: +; r0: 16-bit flags value +; r1: pointer to window struct +; outputs: +; none +set_window_flags: + push r1 + + add r1, 25 + mov.16 [r1], r0 + + pop r1 + ret + ; call this if the user clicks on a window's title bar ; inputs: ; r0: pointer to window struct @@ -529,6 +545,52 @@ add_mouse_event_to_active_window_end: pop r0 ret +; add a mouse event to an inactive window if the mouse was clicked inside the window +; if so, automatically convert the X and Y coords to be relative to the window +; inputs: +; r0-r7: event +; r8: pointer to window struct +; outputs: +; none +add_mouse_event_to_inactive_window: + push r0 + push r2 + push r10 + push r11 + push r12 + + ; save X and Y coords of the click and the event type + mov r10, r1 + mov r11, r2 + mov r12, r0 + + ; get the window's overlay number + mov r0, r8 + call get_window_overlay_number + + ; check if the window's overlay covers the clicked position + mov r2, r0 + mov r0, r10 + mov r1, r11 + call check_if_overlay_covers_position + ; if it doesn't, then end here + ifnz jmp add_mouse_event_to_inactive_window_end + ; if it does, then make the X and Y coords relative to the overlay + call make_coordinates_relative_to_overlay + + ; add the event + mov r2, r1 + mov r1, r0 + mov r0, r12 + call new_window_event +add_mouse_event_to_inactive_window_end: + pop r12 + pop r11 + pop r10 + pop r2 + pop r0 + ret + ; search for an entry in the window list ; inputs: ; r0: entry (pointer to window struct) @@ -565,6 +627,7 @@ search_for_window_list_entry_found: ret ; search for the first non-empty entry in the window list +; this skips over items that have the "always background" flag set ; inputs: ; none ; outputs: @@ -572,6 +635,7 @@ search_for_window_list_entry_found: search_for_nonempty_window_list_entry: push r1 push r2 + push r3 push r31 mov r1, window_list @@ -579,7 +643,14 @@ search_for_nonempty_window_list_entry: mov r31, 31 search_for_nonempty_window_list_entry_loop: cmp [r1], 0 - ifnz jmp search_for_nonempty_window_list_entry_found + ifz jmp search_for_nonempty_window_list_entry_loop_skip + mov r3, [r1] + add r3, 25 + movz.16 r3, [r3] + and r3, WINDOW_FLAG_ALWAYS_BACKGROUND + cmp r3, 0 + ifz jmp search_for_nonempty_window_list_entry_found +search_for_nonempty_window_list_entry_loop_skip: inc r2 add r1, 4 loop search_for_nonempty_window_list_entry_loop @@ -587,6 +658,7 @@ search_for_nonempty_window_list_entry_loop: mov r0, 0xFFFFFFFF pop r31 + pop r3 pop r2 pop r1 ret @@ -595,6 +667,7 @@ search_for_nonempty_window_list_entry_found: mov r0, r2 pop r31 + pop r3 pop r2 pop r1 ret diff --git a/meta/okameron b/meta/okameron index ea08b70..1bc5105 160000 --- a/meta/okameron +++ b/meta/okameron @@ -1 +1 @@ -Subproject commit ea08b7048ebfbea70229e7b7e8a7cbb46fd08d74 +Subproject commit 1bc51054291b3981b62b01a940e025e49412619c