diff --git a/shell.asm b/shell.asm index 5c42648..e42c20b 100644 --- a/shell.asm +++ b/shell.asm @@ -8,6 +8,8 @@ struc window .y resw 1 .data resw 1 .icon resb 1 + .visible resb 1 + .resizable resb 1 .mouse_released_inside resb 1 .status resb 1 .res_x resw 1 @@ -17,6 +19,7 @@ endstruc WINDOW_ID_ICON equ 0 WINDOW_ID_FILE_WINDOW equ 1 +WINDOW_ID_OOM_ERROR equ 2 WINDOW_MOVE equ 1 WINDOW_RESIZE equ 2 @@ -58,16 +61,16 @@ initialize: call set_wallpaper ; Create icon for the disk on the desktop - mov ax, cs - add ax, WINDOW_ID_ICON - xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax - mov [windows + WINDOW_ID_ICON*window.size + window.next], ax mov word [windows + WINDOW_ID_ICON*window.size + window.width], 5 mov word [windows + WINDOW_ID_ICON*window.size + window.height], 3 mov word [windows + WINDOW_ID_ICON*window.size + window.x], 1 mov word [windows + WINDOW_ID_ICON*window.size + window.y], 1 mov word [windows + WINDOW_ID_ICON*window.size + window.data], disk_icon mov byte [windows + WINDOW_ID_ICON*window.size + window.icon], 1 + mov ax, cs + add ax, WINDOW_ID_ICON + mov si, windows + WINDOW_ID_ICON*window.size + call show_window ; Initialize file window but don't show it mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.width], 40 @@ -75,8 +78,14 @@ initialize: mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.x], 10 mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.y], 4 mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.data], file_window - mov byte [windows + WINDOW_ID_FILE_WINDOW*window.size + window.icon], 0 - mov byte [windows + WINDOW_ID_FILE_WINDOW*window.size + window.mouse_released_inside], 0 + mov byte [windows + WINDOW_ID_FILE_WINDOW*window.size + window.resizable], 1 + + ; Initialize error dialogs + mov word [windows + WINDOW_ID_OOM_ERROR*window.size + window.width], 13 + mov word [windows + WINDOW_ID_OOM_ERROR*window.size + window.height], 2 + mov word [windows + WINDOW_ID_OOM_ERROR*window.size + window.x], 30 + mov word [windows + WINDOW_ID_OOM_ERROR*window.size + window.y], 10 + mov word [windows + WINDOW_ID_OOM_ERROR*window.size + window.data], oom_error_dialog call request_redraw @@ -300,19 +309,30 @@ click: cmp byte [si + window.icon], 0 je .file_window .icon: - call show_file_window + mov ax, cs + add ax, WINDOW_ID_FILE_WINDOW + mov si, windows + WINDOW_ID_FILE_WINDOW*window.size + call show_window + call render_file_window jmp .end .file_window: call raise_window + ; Save window ID + mov bp, ax + cmp bx, [si + window.y] jne .not_title_bar - ; If clicked the window close button + ; Resize button mov ax, [si + window.x] + cmp byte [si + window.resizable], 0 + je .not_resizable cmp ax, cx je .resize + .not_resizable: + ; Window close button add ax, [si + window.width] dec ax cmp ax, cx @@ -332,7 +352,7 @@ click: jmp .end .close: - call hide_file_window + call hide_window jmp .end @@ -495,43 +515,6 @@ move: pop dx ret -show_file_window: - cmp byte [file_window_visible], 0 - jne .already_visible - - push ax - - mov ax, PONYDOS_SEG - mov es, ax - - mov ax, cs - add ax, WINDOW_ID_FILE_WINDOW - xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax - mov si, windows + WINDOW_ID_FILE_WINDOW*window.size - mov [si + window.next], ax - - ; Populate file window contents - call render_file_window - - pop ax - - mov byte [file_window_visible], 1 - - call request_redraw - - .already_visible: - ret - -hide_file_window: - mov cx, cs - add cx, WINDOW_ID_FILE_WINDOW - call unhook_window - - mov byte [file_window_visible], 0 - - call request_redraw - ret - ; out: ; clobbers everything launch: @@ -591,7 +574,11 @@ launch: jz .found_free_segment inc si loop .find_free_segment - ; TODO: Display an alert on OOM error + ; Display an error dialog if we can't allocate a segment + mov ax, cs + add ax, WINDOW_ID_OOM_ERROR + mov si, windows + WINDOW_ID_OOM_ERROR*window.size + call show_window pop cx pop ax jmp .end @@ -673,7 +660,7 @@ forward_event: ; in: ; bx = valid window id for this process ; out: -; si = pointer to window's data block +; si = pointer to window structure get_window: push bx @@ -693,6 +680,62 @@ get_window: pop bx ret +; in: +; ax = window ID +; si = pointer to window structure +show_window: + push ax + + cmp byte [si + window.visible], 0 + je .not_yet_visible + call raise_window + jmp .end + + .not_yet_visible: + call hook_window + mov [si + window.next], ax + + mov byte [si + window.visible], 1 + + call request_redraw + + .end: + pop ax + ret + +; in: +; bp = window ID +; si = pointer to window structure +hide_window: + push cx + + mov cx, bp + call unhook_window + + mov byte [windows + WINDOW_ID_FILE_WINDOW*window.size + window.visible], 0 + + call request_redraw + + pop cx + ret + +; in: +; ax = window ID to hook +; out: +; ax = next window ID +hook_window: + push bp + push es + + mov bp, PONYDOS_SEG + mov es, bp + + xchg [es:GLOBAL_WINDOW_CHAIN_HEAD], ax + + pop es + pop bp + ret + ; in: ; cx = window ID to unhook unhook_window: @@ -1025,9 +1068,16 @@ disk_icon: db 0x00, 0x0f, 0x00, 0x0f, 0x09, 0x0f, 0x00, 0x0f, 0x00, 0x0f db 0x00, 0x0f, 0x00, 0x0f, '|', 0x0f, 0x00, 0x0f, 0x00, 0x0f +oom_error_dialog: + db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f + times 13-5-1 db 0x00, 0x0f + db 'x', 0x0f + db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0, ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0, 'y', 0xf0 + windows: times window.size db 0 times window.size db 0 + times window.size db 0 launch_filename times FS_DIRENT_NAME_SIZE db 0