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
|
||||
ifz call new_event
|
||||
|
||||
cmp [active_window], 0
|
||||
cmp.8 [active_window_offset], 0xFF
|
||||
ifz rjmp event_manager_task_loop_end
|
||||
|
||||
; mouse
|
||||
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
|
||||
ifz call add_mouse_event_to_active_window
|
||||
ifz call event_manager_task_mouse_event
|
||||
|
||||
; keyboard
|
||||
cmp r0, EVENT_TYPE_KEY_DOWN
|
||||
|
@ -52,3 +52,75 @@ event_manager_task_loop:
|
|||
event_manager_task_loop_end:
|
||||
call yield_task
|
||||
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
|
||||
mov.8 [r10], r11
|
||||
|
||||
; finally, set the properties of the overlay
|
||||
; then, set the properties of the overlay
|
||||
push r0
|
||||
push r1
|
||||
push r2
|
||||
|
@ -119,9 +119,19 @@ new_window:
|
|||
call fill_overlay
|
||||
pop r0
|
||||
|
||||
mov [active_window], r0
|
||||
; then, draw the title bar
|
||||
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 r11
|
||||
pop r10
|
||||
|
@ -153,10 +163,23 @@ destroy_window:
|
|||
mov r0, [r1]
|
||||
call free_memory
|
||||
|
||||
; disable the window's overlay
|
||||
add r1, 16
|
||||
movz.8 r0, [r1]
|
||||
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 r0
|
||||
ret
|
||||
|
@ -244,6 +267,35 @@ move_window:
|
|||
pop r0
|
||||
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
|
||||
; inputs:
|
||||
; r0: color
|
||||
|
@ -377,7 +429,11 @@ draw_title_bar_to_window_loop:
|
|||
; outputs:
|
||||
; none
|
||||
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
|
||||
|
||||
ret
|
||||
|
@ -401,7 +457,8 @@ add_mouse_event_to_active_window:
|
|||
mov r12, r0
|
||||
|
||||
; 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
|
||||
|
||||
; check if the window's overlay covers the clicked position
|
||||
|
@ -427,6 +484,125 @@ add_mouse_event_to_active_window_end:
|
|||
pop r0
|
||||
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:
|
||||
; 1x16 tile
|
||||
data.32 0x00000000
|
||||
|
@ -464,7 +640,9 @@ window_title_bar_patterns:
|
|||
data.32 0xFFFFFFFF
|
||||
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_manager_task.asm"
|
||||
#include "window/overlay.asm"
|
||||
|
|
Loading…
Reference in New Issue
Block a user