kernel: A more complete window manager implementation
It's currently pretty buggy, but at least it's better than what we had before :P
This commit is contained in:
parent
c6919d4168
commit
a68e584c82
|
@ -35,14 +35,14 @@ event_manager_task_loop:
|
||||||
cmp r0, EVENT_TYPE_MENU_UPDATE
|
cmp r0, EVENT_TYPE_MENU_UPDATE
|
||||||
ifz call new_event
|
ifz call new_event
|
||||||
|
|
||||||
cmp [active_window], 0
|
cmp.8 [active_window_offset], 0xFF
|
||||||
ifz rjmp event_manager_task_loop_end
|
ifz rjmp event_manager_task_loop_end
|
||||||
|
|
||||||
; mouse
|
; mouse
|
||||||
cmp r0, EVENT_TYPE_MOUSE_CLICK
|
cmp r0, EVENT_TYPE_MOUSE_CLICK
|
||||||
ifz call add_mouse_event_to_active_window
|
ifz call event_manager_task_mouse_event
|
||||||
cmp r0, EVENT_TYPE_MOUSE_RELEASE
|
cmp r0, EVENT_TYPE_MOUSE_RELEASE
|
||||||
ifz call add_mouse_event_to_active_window
|
ifz call event_manager_task_mouse_event
|
||||||
|
|
||||||
; keyboard
|
; keyboard
|
||||||
cmp r0, EVENT_TYPE_KEY_DOWN
|
cmp r0, EVENT_TYPE_KEY_DOWN
|
||||||
|
@ -52,3 +52,75 @@ event_manager_task_loop:
|
||||||
event_manager_task_loop_end:
|
event_manager_task_loop_end:
|
||||||
call yield_task
|
call yield_task
|
||||||
rjmp event_manager_task_loop
|
rjmp event_manager_task_loop
|
||||||
|
|
||||||
|
event_manager_task_mouse_event:
|
||||||
|
push r0
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
|
||||||
|
; find which overlay was clicked on
|
||||||
|
mov r0, r1
|
||||||
|
mov r1, r2
|
||||||
|
call find_overlay_convering_position
|
||||||
|
cmp r0, 0xFFFFFFFF
|
||||||
|
ifz pop r2
|
||||||
|
ifz pop r1
|
||||||
|
ifz pop r0
|
||||||
|
ifz ret
|
||||||
|
push r0
|
||||||
|
|
||||||
|
; get the overlay number of the active window
|
||||||
|
movz.8 r0, [active_window_offset]
|
||||||
|
call window_list_offset_to_struct
|
||||||
|
call get_window_overlay_number
|
||||||
|
|
||||||
|
; check if the click was inside the active window
|
||||||
|
; otherwise, activate the clicked window
|
||||||
|
pop r1
|
||||||
|
cmp r0, r1
|
||||||
|
ifnz jmp 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:
|
||||||
|
mov r2, r1
|
||||||
|
mov r1, r0
|
||||||
|
mov r0, r2
|
||||||
|
|
||||||
|
; r0: clicked window overlay number
|
||||||
|
; r1: currently active window overlay number
|
||||||
|
|
||||||
|
; get the window structs of the two windows
|
||||||
|
call get_window_with_overlay
|
||||||
|
mov r2, r0
|
||||||
|
mov r0, r1
|
||||||
|
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
|
||||||
|
cmp r1, 0x00000000
|
||||||
|
ifz pop r2
|
||||||
|
ifz pop r1
|
||||||
|
ifz pop r0
|
||||||
|
ifz ret
|
||||||
|
|
||||||
|
; swap the two
|
||||||
|
call swap_windows
|
||||||
|
|
||||||
|
; mark the clicked window as the active window
|
||||||
|
mov r0, r1
|
||||||
|
call search_for_window_list_entry
|
||||||
|
mov.8 [active_window_offset], r0
|
||||||
|
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
pop r0
|
||||||
|
ret
|
||||||
|
|
95
kernel/window/overlay.asm
Normal file
95
kernel/window/overlay.asm
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
; overlay routines for window management
|
||||||
|
|
||||||
|
; given a position on screen, find which enabled overlay (if any) is covering it
|
||||||
|
; if multiple overlays are covering the same position, the highest priority one will be returned
|
||||||
|
; overlay 31 (the mouse cursor) is ignored
|
||||||
|
; inputs:
|
||||||
|
; r0: X coordinate
|
||||||
|
; r1: Y coordinate
|
||||||
|
; outputs:
|
||||||
|
; r0: overlay number, or 0xFFFFFFFF if none
|
||||||
|
find_overlay_convering_position:
|
||||||
|
push r2
|
||||||
|
push r31
|
||||||
|
|
||||||
|
mov r31, 31
|
||||||
|
find_overlay_convering_position_loop:
|
||||||
|
mov r2, r31
|
||||||
|
dec r2
|
||||||
|
call check_if_enabled_overlay_covers_position
|
||||||
|
ifz jmp find_overlay_convering_position_found
|
||||||
|
loop find_overlay_convering_position_loop
|
||||||
|
; none found, return 0xFFFFFFFF
|
||||||
|
mov r0, 0xFFFFFFFF
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
ret
|
||||||
|
find_overlay_convering_position_found:
|
||||||
|
; found one, return its overlay number
|
||||||
|
mov r0, r2
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
ret
|
||||||
|
|
||||||
|
; swap two overlays. this has the effect of swapping their priorities
|
||||||
|
; this does *not* effect the enable status of either overlay
|
||||||
|
; FIXME: this could use the stack instead
|
||||||
|
; inputs:
|
||||||
|
; r0: overlay number
|
||||||
|
; r1: overlay number
|
||||||
|
; outputs:
|
||||||
|
; none
|
||||||
|
swap_overlays:
|
||||||
|
push r10
|
||||||
|
|
||||||
|
; save first overlay
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000000
|
||||||
|
in [overlay_0_position], r10
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000100
|
||||||
|
in [overlay_0_size], r10
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000200
|
||||||
|
in [overlay_0_ptr], r10
|
||||||
|
|
||||||
|
; save second overlay
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000000
|
||||||
|
in [overlay_1_position], r10
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000100
|
||||||
|
in [overlay_1_size], r10
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000200
|
||||||
|
in [overlay_1_ptr], r10
|
||||||
|
|
||||||
|
; swap
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000000
|
||||||
|
out r10, [overlay_0_position]
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000100
|
||||||
|
out r10, [overlay_0_size]
|
||||||
|
mov r10, r1
|
||||||
|
or r10, 0x80000200
|
||||||
|
out r10, [overlay_0_ptr]
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000000
|
||||||
|
out r10, [overlay_1_position]
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000100
|
||||||
|
out r10, [overlay_1_size]
|
||||||
|
mov r10, r0
|
||||||
|
or r10, 0x80000200
|
||||||
|
out r10, [overlay_1_ptr]
|
||||||
|
|
||||||
|
pop r10
|
||||||
|
ret
|
||||||
|
|
||||||
|
overlay_0_position: data.32 0x00000000
|
||||||
|
overlay_0_size: data.32 0x00000000
|
||||||
|
overlay_0_ptr: data.32 0x00000000
|
||||||
|
overlay_1_position: data.32 0x00000000
|
||||||
|
overlay_1_size: data.32 0x00000000
|
||||||
|
overlay_1_ptr: data.32 0x00000000
|
|
@ -94,7 +94,7 @@ new_window:
|
||||||
add r10, 24
|
add r10, 24
|
||||||
mov.8 [r10], r11
|
mov.8 [r10], r11
|
||||||
|
|
||||||
; finally, set the properties of the overlay
|
; then, set the properties of the overlay
|
||||||
push r0
|
push r0
|
||||||
push r1
|
push r1
|
||||||
push r2
|
push r2
|
||||||
|
@ -119,9 +119,19 @@ new_window:
|
||||||
call fill_overlay
|
call fill_overlay
|
||||||
pop r0
|
pop r0
|
||||||
|
|
||||||
mov [active_window], r0
|
; then, draw the title bar
|
||||||
call draw_title_bar_to_window
|
call draw_title_bar_to_window
|
||||||
|
|
||||||
|
; finally, add this window to the window list
|
||||||
|
push r0
|
||||||
|
mov r0, 0x00000000
|
||||||
|
call search_for_window_list_entry
|
||||||
|
mov.8 [active_window_offset], r0
|
||||||
|
mul r0, 4
|
||||||
|
add r0, window_list
|
||||||
|
pop r1
|
||||||
|
mov [r0], r1
|
||||||
|
|
||||||
pop r12
|
pop r12
|
||||||
pop r11
|
pop r11
|
||||||
pop r10
|
pop r10
|
||||||
|
@ -153,10 +163,23 @@ destroy_window:
|
||||||
mov r0, [r1]
|
mov r0, [r1]
|
||||||
call free_memory
|
call free_memory
|
||||||
|
|
||||||
|
; disable the window's overlay
|
||||||
add r1, 16
|
add r1, 16
|
||||||
movz.8 r0, [r1]
|
movz.8 r0, [r1]
|
||||||
call disable_overlay
|
call disable_overlay
|
||||||
|
|
||||||
|
; remove the window from the window list
|
||||||
|
sub r1, 24
|
||||||
|
mov r0, r1
|
||||||
|
call search_for_window_list_entry
|
||||||
|
mul r0, 4
|
||||||
|
add r0, window_list
|
||||||
|
mov [r0], 0
|
||||||
|
|
||||||
|
; set the active window to whatever entry is found first
|
||||||
|
call search_for_nonempty_window_list_entry
|
||||||
|
mov.8 [active_window_offset], r0
|
||||||
|
|
||||||
pop r1
|
pop r1
|
||||||
pop r0
|
pop r0
|
||||||
ret
|
ret
|
||||||
|
@ -244,6 +267,35 @@ move_window:
|
||||||
pop r0
|
pop r0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; swap two windows
|
||||||
|
; inputs:
|
||||||
|
; r0: pointer to window struct
|
||||||
|
; r1: pointer to window struct
|
||||||
|
; outputs:
|
||||||
|
; none
|
||||||
|
swap_windows:
|
||||||
|
push r0
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
|
||||||
|
mov r2, r0
|
||||||
|
mov r3, r1
|
||||||
|
|
||||||
|
add r2, 24
|
||||||
|
movz.8 r0, [r2]
|
||||||
|
add r3, 24
|
||||||
|
movz.8 r1, [r3]
|
||||||
|
call swap_overlays
|
||||||
|
movz.8 [r2], r1
|
||||||
|
movz.8 [r3], r0
|
||||||
|
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
pop r0
|
||||||
|
ret
|
||||||
|
|
||||||
; fill a whole window with a color
|
; fill a whole window with a color
|
||||||
; inputs:
|
; inputs:
|
||||||
; r0: color
|
; r0: color
|
||||||
|
@ -377,7 +429,11 @@ draw_title_bar_to_window_loop:
|
||||||
; outputs:
|
; outputs:
|
||||||
; none
|
; none
|
||||||
add_event_to_active_window:
|
add_event_to_active_window:
|
||||||
mov r8, [active_window]
|
push r0
|
||||||
|
movz.8 r0, [active_window_offset]
|
||||||
|
call window_list_offset_to_struct
|
||||||
|
mov r8, r0
|
||||||
|
pop r0
|
||||||
call new_window_event
|
call new_window_event
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -401,7 +457,8 @@ add_mouse_event_to_active_window:
|
||||||
mov r12, r0
|
mov r12, r0
|
||||||
|
|
||||||
; get the window's overlay number
|
; get the window's overlay number
|
||||||
mov r0, [active_window]
|
movz.8 r0, [active_window_offset]
|
||||||
|
call window_list_offset_to_struct
|
||||||
call get_window_overlay_number
|
call get_window_overlay_number
|
||||||
|
|
||||||
; check if the window's overlay covers the clicked position
|
; check if the window's overlay covers the clicked position
|
||||||
|
@ -427,6 +484,125 @@ add_mouse_event_to_active_window_end:
|
||||||
pop r0
|
pop r0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; search for an entry in the window list
|
||||||
|
; inputs:
|
||||||
|
; r0: entry (pointer to window struct)
|
||||||
|
; outputs:
|
||||||
|
; r0: window list offset, or 0xFFFFFFFF if not found
|
||||||
|
search_for_window_list_entry:
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r31
|
||||||
|
|
||||||
|
mov r1, window_list
|
||||||
|
mov r2, 0
|
||||||
|
mov r31, 31
|
||||||
|
search_for_window_list_entry_loop:
|
||||||
|
cmp [r1], r0
|
||||||
|
ifz jmp search_for_window_list_entry_found
|
||||||
|
inc r2
|
||||||
|
add r1, 4
|
||||||
|
loop search_for_window_list_entry_loop
|
||||||
|
; not found, return 0xFFFFFFFF
|
||||||
|
mov r0, 0xFFFFFFFF
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
search_for_window_list_entry_found:
|
||||||
|
; found the entry, return its offset
|
||||||
|
mov r0, r2
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; search for the first non-empty entry in the window list
|
||||||
|
; inputs:
|
||||||
|
; none
|
||||||
|
; outputs:
|
||||||
|
; r0: window list offset, or 0xFFFFFFFF if not found
|
||||||
|
search_for_nonempty_window_list_entry:
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r31
|
||||||
|
|
||||||
|
mov r1, window_list
|
||||||
|
mov r2, 0
|
||||||
|
mov r31, 31
|
||||||
|
search_for_nonempty_window_list_entry_loop:
|
||||||
|
cmp [r1], 0
|
||||||
|
ifnz jmp search_for_nonempty_window_list_entry_found
|
||||||
|
inc r2
|
||||||
|
add r1, 4
|
||||||
|
loop search_for_nonempty_window_list_entry_loop
|
||||||
|
; not found, return 0xFFFFFFFF
|
||||||
|
mov r0, 0xFFFFFFFF
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
search_for_nonempty_window_list_entry_found:
|
||||||
|
; found the entry, return its offset
|
||||||
|
mov r0, r2
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; given an overlay number, get the window struct of the window associated with that overlay
|
||||||
|
; inputs:
|
||||||
|
; r0: overlay number
|
||||||
|
; outputs:
|
||||||
|
; r0: pointer to window struct, or 0x00000000 if not found
|
||||||
|
get_window_with_overlay:
|
||||||
|
push r1
|
||||||
|
push r2
|
||||||
|
push r3
|
||||||
|
push r31
|
||||||
|
|
||||||
|
mov r1, window_list
|
||||||
|
mov r31, 31
|
||||||
|
get_window_with_overlay_loop:
|
||||||
|
mov r2, [r1]
|
||||||
|
add r2, 24
|
||||||
|
cmp.8 [r2], r0
|
||||||
|
ifz jmp get_window_with_overlay_found
|
||||||
|
add r1, 4
|
||||||
|
loop get_window_with_overlay_loop
|
||||||
|
; not found, return 0
|
||||||
|
mov r0, 0
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
get_window_with_overlay_found:
|
||||||
|
; found the entry, return the pointer to its struct
|
||||||
|
mov r0, [r1]
|
||||||
|
|
||||||
|
pop r31
|
||||||
|
pop r3
|
||||||
|
pop r2
|
||||||
|
pop r1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; get a window struct pointer from the window list
|
||||||
|
; inputs:
|
||||||
|
; r0: window list offset
|
||||||
|
; outputs:
|
||||||
|
; r0: pointer to window struct
|
||||||
|
window_list_offset_to_struct:
|
||||||
|
mul r0, 4
|
||||||
|
add r0, window_list
|
||||||
|
mov r0, [r0]
|
||||||
|
ret
|
||||||
|
|
||||||
window_title_bar_patterns:
|
window_title_bar_patterns:
|
||||||
; 1x16 tile
|
; 1x16 tile
|
||||||
data.32 0x00000000
|
data.32 0x00000000
|
||||||
|
@ -464,7 +640,9 @@ window_title_bar_patterns:
|
||||||
data.32 0xFFFFFFFF
|
data.32 0xFFFFFFFF
|
||||||
data.32 0x00000000
|
data.32 0x00000000
|
||||||
|
|
||||||
active_window: data.32 0
|
active_window_offset: data.8 0xFF
|
||||||
|
window_list: data.fill 0, 124 ; 31 window structs * 4 bytes each
|
||||||
|
|
||||||
#include "window/event.asm"
|
#include "window/event.asm"
|
||||||
#include "window/event_manager_task.asm"
|
#include "window/event_manager_task.asm"
|
||||||
|
#include "window/overlay.asm"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user