From 313453f5b364d43b4d9dae68937816292c1035f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Mon, 20 Mar 2023 21:42:59 +0200 Subject: [PATCH] Implement window unhooking --- debug.inc | 7 +++ ponydos_static.inc | 1 + shell.asm | 103 ++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/debug.inc b/debug.inc index f7be956..8845139 100644 --- a/debug.inc +++ b/debug.inc @@ -27,6 +27,13 @@ hexprint4: pop ax ret +space: + push ax + mov ax, 0x0e00 + ' ' + int 0x10 + pop ax + ret + hang: hlt jmp hang diff --git a/ponydos_static.inc b/ponydos_static.inc index 280b9af..acefa99 100644 --- a/ponydos_static.inc +++ b/ponydos_static.inc @@ -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 diff --git a/shell.asm b/shell.asm index c83b9e6..d5e013b 100644 --- a/shell.asm +++ b/shell.asm @@ -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