Implement window unhooking

This commit is contained in:
Juhani Krekelä 2023-03-20 21:42:59 +02:00
parent cd98221d85
commit 313453f5b3
3 changed files with 106 additions and 5 deletions

View File

@ -27,6 +27,13 @@ hexprint4:
pop ax
ret
space:
push ax
mov ax, 0x0e00 + ' '
int 0x10
pop ax
ret
hang:
hlt
jmp hang

View File

@ -9,6 +9,7 @@ FS_FILE_MAX_SIZE equ 128
WM_PAINT equ 0
WM_MOUSE equ 1
WM_KEYBOARD equ 2
WM_UNHOOK equ 3
MOUSE_PRIMARY equ 0x01
MOUSE_SECONDARY equ 0x02

103
shell.asm
View File

@ -77,7 +77,6 @@ initialize:
retf
process_event:
push ax
push bx
push cx
push dx
@ -106,7 +105,13 @@ process_event:
cmp al, WM_KEYBOARD
jne .not_keyboard
call keyboard
.not_keyboard
jmp .end
.not_keyboard:
cmp al, WM_UNHOOK
jne .not_remove
call unhook
.not_remove:
.end:
pop es
@ -117,7 +122,6 @@ process_event:
pop dx
pop cx
pop bx
pop ax
retf
paint:
@ -142,6 +146,8 @@ mouse:
push cx
push bx
; Y
xor bx, bx
mov bl, ch
@ -161,11 +167,15 @@ mouse:
cmp [si + window.height], bx
jle .outside
pop bx
mov si, [si + window.data]
add si, 18
test dl, MOUSE_PRIMARY
jz .not_clicking
.clicking:
call raise_window
mov al, '*'
xchg byte [si], al
cmp al, '*'
@ -184,6 +194,7 @@ mouse:
ret
.outside:
pop bx
pop cx
mov bx, [si + window.next]
call forward_event
@ -197,11 +208,40 @@ keyboard:
call request_redraw
ret
unhook:
call get_window
cmp bx, cx
je .match
push bx
; Forward the event
mov bx, [si + window.next]
call forward_event
; Update next ID
; If window.next was zero, forward_event will also return zero so
; this is safe in all cases
mov [si + window.next], ax
; Return own ID to keep self in the chain
pop ax
ret
.match:
; Return next ID in the chain to unhook
mov ax, [si + window.next]
ret
; in:
; bx = valid window id for this process
; out:
; si = pointer to window's data block
get_window:
push bx
mov si, cs
sub bx, si
@ -215,6 +255,7 @@ get_window:
pop dx
pop ax
pop bx
ret
request_redraw:
@ -229,6 +270,50 @@ request_redraw:
pop es
ret
; in:
; cx = window ID to unhook
unhook_window:
push ax
push bx
push es
mov bx, PONYDOS_SEG
mov es, bx
mov bx, [es:GLOBAL_WINDOW_CHAIN_HEAD]
mov al, WM_UNHOOK
call forward_event
mov [es:GLOBAL_WINDOW_CHAIN_HEAD], ax
pop es
pop bx
pop ax
ret
; in:
; bx = window ID to raise
raise_window:
push cx
push si
push es
call get_window
mov cx, bx
call unhook_window
mov cx, PONYDOS_SEG
mov es, cx
mov cx, bx
xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], cx
mov [si + window.next], cx
pop es
pop si
pop cx
ret
; in
; cx = height of window (>= 1)
; dx = width of window in characters
@ -388,10 +473,12 @@ strlen:
; in:
; bx = window ID
; out:
; clobbers bp
; ax = return value of event handler; 0 if window ID is 0
forward_event:
push bp
cmp bx, 0
je .end
je .id_is_zero
push cs ; Return segment
mov bp, .end
@ -404,7 +491,13 @@ forward_event:
push bp ; Call offset
retf
.id_is_zero:
; This gets skipped over in normal execution, because it
; explicitly returns to .end
xor ax, ax
.end:
pop bp
ret
wallpaper_name db 'wallpaper.bin', 0