Add error handling and popups in viewer

This commit is contained in:
shikhin 2023-03-27 16:04:52 +05:30
parent c6aa2ac3d1
commit 75a9a51191
3 changed files with 190 additions and 100 deletions

View File

@ -6,10 +6,9 @@ Feel free to add anything you think would fit in
* refactor shell.asm a bit:
- add/verify function header comments
* basic error handling in viewer
* error pop-ups in all programs
* a release-able README
### Nice to have
* more file listing windows
* ponysay

View File

@ -75,7 +75,7 @@ initialize:
; Initialize file window but don't show it
mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.width], 40
mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.height], 16
mov word [windows + WINDOW_ID_FILE_WINDOW*window.size + window.height], 17
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

View File

@ -130,7 +130,10 @@ filename_char_del:
; out:
; clobbers everything
filename_ok:
; TODO: error management for empty file filename
; Just ignore if there's no filename.
cmp byte [filename_window_data.filename], 0
je .end
mov cx, FS_DIRENT_NAME_SIZE
mov di, window_title
mov si, filename_window_data.filename
@ -142,9 +145,22 @@ filename_ok:
mov si, window_title
xor dx, dx ; do create empty file
call PONYDOS_SEG:SYS_OPEN_FILE ; TODO: error management
call PONYDOS_SEG:SYS_OPEN_FILE
test ax, ax
jnz .got_file
mov si, ood_window
call raise_error
ret
call allocate_segment ; TODO: error management
.got_file:
call allocate_segment
test dx, dx
jnz .got_memory
mov si, oom_window
call raise_error
ret
.got_memory:
mov [cur_file_address + 2], dx
mov word [cur_file_address], 0
mov word [beg_file_address], 0
@ -153,7 +169,7 @@ filename_ok:
mov es, dx
xor bx, bx
xor di, di ; read
call PONYDOS_SEG:SYS_MODIFY_SECTORS ; TODO: error management
call PONYDOS_SEG:SYS_MODIFY_SECTORS
pop es
mov ch, cl
@ -161,22 +177,17 @@ filename_ok:
shl cx, 1 ; Multiply by 512
mov [end_file_address], cx
; TODO: does this need to be restructured to be more safe to mouse
; interrupts? (I think not.)
mov ax, [text_window_width]
mov [window_width], ax
mov ax, [text_window_height]
mov [window_height], ax
mov ax, [text_window_x]
mov [window_x], ax
mov ax, [text_window_y]
mov [window_y], ax
mov si, text_window
mov di, window
mov cx, window_struc.size
rep movsb
mov byte [file_opened], 1
call render_window
call request_redraw
.end:
ret
; ------------------------------------------------------------------
@ -196,9 +207,9 @@ print_file:
lds si, [cur_file_address]
mov cx, [cs:window_height]
mov cx, [cs:window.height]
dec cx
mov dx, [cs:window_width]
mov dx, [cs:window.width]
mov bl, 1 ; Haven't read anything yet
.window_loop:
push di
@ -233,11 +244,11 @@ print_file:
dec dx
jnz .line_loop
.next_line:
mov dx, [cs:window_width]
mov dx, [cs:window.width]
pop di
add di, [cs:window_width]
add di, [cs:window_width]
add di, [cs:window.width]
add di, [cs:window.width]
loop .window_loop
.ret:
@ -355,16 +366,12 @@ event_paint:
mov bx, [window_next]
call send_event
mov si, filename_window_data
cmp byte [file_opened], 0
je .file_not_opened
mov si, text_window_data
.file_not_opened:
mov bx, [window_width] ; Buffer width, usually same as window width
mov cx, [window_width]
mov dx, [window_height]
mov di, [window_x]
mov bp, [window_y]
mov bx, [window.width] ; Buffer width, usually same as window width
mov cx, [window.width]
mov dx, [window.height]
mov di, [window.x]
mov bp, [window.y]
mov si, [window.data_address]
cmp di, 0
jge .not_clip_left
@ -439,16 +446,16 @@ event_mouse:
.not_resizing:
; Check if the mouse is outside our window
cmp cx, [window_x]
cmp cx, [window.x]
jl .outside ; x < window_x
cmp bx, [window_y]
cmp bx, [window.y]
jl .outside ; y < window_y
mov ax, [window_x]
add ax, [window_width]
mov ax, [window.x]
add ax, [window.width]
cmp ax, cx
jle .outside ; window_x + window_width <= x
mov ax, [window_y]
add ax, [window_height]
mov ax, [window.y]
add ax, [window.height]
cmp ax, bx
jle .outside ; window_y + window_height <= y
@ -519,30 +526,24 @@ event_click:
call request_redraw
; Did the user click the title bar?
cmp [window_y], bx
cmp [window.y], bx
jne .not_title_bar
.title_bar:
; Did the user click the window close button?
mov ax, [window_x]
add ax, [window_width]
mov ax, [window.x]
add ax, [window.width]
dec ax
cmp ax, cx
jne .not_close
.close:
call unhook_self_from_window_chain
; Nothing can call into us again after we unhook
; the window, so deallocate the memory we have
; reserved
call deallocate_own_memory
; We don't need to call request_redraw here, since
; it will be called unconditionally above
call close_window
jmp .end
.not_close:
; Did the user click on the resize button?
cmp byte [file_opened], 0
je .not_resize ; Can't resize while entering filename
cmp [window_x], cx
cmp [window.x], cx
jne .not_resize
.resize:
mov byte [window_status], WINDOW_STATUS_RESIZE
@ -552,7 +553,7 @@ event_click:
; Clicking on the title bar signals beginning of a window
; move
mov byte [window_status], WINDOW_STATUS_MOVE
mov ax, [window_x]
mov ax, [window.x]
sub ax, cx
mov [window_move_x_offset], ax
jmp .end
@ -561,10 +562,10 @@ event_click:
cmp byte [file_opened], 0
jne .not_filename_window
.filename_window:
sub bx, [window_y]
sub cx, [window_x]
sub bx, [window.y]
sub cx, [window.x]
mov ax, [window_width]
mov ax, [window.width]
shl ax, 1
mul bx
add ax, cx
@ -589,14 +590,14 @@ event_click:
jmp .end
.not_filename_window:
mov ax, [window_x]
add ax, [window_width]
mov ax, [window.x]
add ax, [window.width]
dec ax
cmp ax, cx
jne .not_scroll_bar
; Scroll up button?
mov ax, [window_y]
mov ax, [window.y]
inc ax
cmp ax, bx
jne .not_scroll_up
@ -611,7 +612,7 @@ event_click:
.not_scroll_up:
; Scroll down button?
add ax, [window_height]
add ax, [window.height]
dec ax
dec ax
cmp ax, bx
@ -640,6 +641,8 @@ event_click:
event_keyboard:
cmp byte [file_opened], 0
jne .file_opened
cmp word [window.data_address], filename_window_data
jne .ret ; error windows
.file_not_opened:
cmp ch, 0x0e
jne .not_backspace
@ -736,6 +739,27 @@ event_unhook:
; Event handler subroutines
; ------------------------------------------------------------------
; out:
; clobbers si, di, cx
close_window:
cmp word [window.data_address], oom_window_data
je .error_window
cmp word [window.data_address], ood_window_data
je .error_window
.not_error_window:
; Shut off app
call unhook_self_from_window_chain
call deallocate_own_memory
ret
.error_window:
mov si, filename_window
mov di, window
mov cx, window_struc.size
rep movsb
call request_redraw
ret
; in:
; bx = Y
; cx = X
@ -748,15 +772,15 @@ move_window:
add ax, [window_move_x_offset]
; Only do an update if something has changed. Reduces flicker
cmp [window_x], ax
cmp [window.x], ax
jne .update_location
cmp [window_y], bx
cmp [window.y], bx
jne .update_location
jmp .end
.update_location:
mov [window_x], ax
mov [window_y], bx
mov [window.x], ax
mov [window.y], bx
call request_redraw
.end:
@ -772,8 +796,8 @@ resize_window:
push bp
; Calculate new width
mov ax, [window_width]
add ax, [window_x]
mov ax, [window.width]
add ax, [window.x]
sub ax, cx
cmp ax, WINDOW_MIN_WIDTH
@ -787,8 +811,8 @@ resize_window:
.width_small_enough:
; Calculate new height
mov bp, [window_height]
add bp, [window_y]
mov bp, [window.height]
add bp, [window.y]
sub bp, bx
cmp bp, WINDOW_MIN_HEIGHT
@ -802,24 +826,24 @@ resize_window:
.height_small_engough:
; Only do an update if something has changed. Reduces flicker
cmp [window_width], ax
cmp [window.width], ax
jne .update_size
cmp [window_height], bp
cmp [window.height], bp
jne .update_size
jmp .end
.update_size:
mov bx, [window_x]
add bx, [window_width]
mov bx, [window.x]
add bx, [window.width]
sub bx, ax
mov [window_x], bx
mov [window_width], ax
mov [window.x], bx
mov [window.width], ax
mov bx, [window_y]
add bx, [window_height]
mov bx, [window.y]
add bx, [window.height]
sub bx, bp
mov [window_y], bx
mov [window_height], bp
mov [window.y], bx
mov [window.height], bp
call render_window
@ -839,8 +863,8 @@ render_window:
; Clear window to be black-on-white
mov di, text_window_data
mov ax, [window_width]
mov cx, [window_height]
mov ax, [window.width]
mov cx, [window.height]
mul cx
mov cx, ax
mov ax, 0xf000 ; Attribute is in the high byte
@ -849,14 +873,14 @@ render_window:
; Set title bar to be white-on-black
mov di, text_window_data
mov ax, 0x0f00
mov cx, [window_width]
mov cx, [window.width]
rep stosw
; Add title bar buttons
mov di, text_window_data
mov byte [di], 0x17 ; Resize arrow
add di, [window_width]
add di, [window_width]
add di, [window.width]
add di, [window.width]
sub di, 2
mov byte [di], 'x' ; Close button
@ -864,7 +888,7 @@ render_window:
mov di, text_window_data
add di, 2
mov si, window_title
mov cx, [window_width]
mov cx, [window.width]
dec cx
dec cx
cmp cx, FS_DIRENT_NAME_SIZE
@ -878,17 +902,17 @@ render_window:
; Print text
mov di, text_window_data
add di, [window_width]
add di, [window_width]
add di, [window.width]
add di, [window.width]
call print_file
add di, [window_width]
add di, [window_width]
add di, [window.width]
add di, [window.width]
sub di, 2
mov byte [di], 0x1E ; up
mov ax, [window_width]
mov cx, [window_height]
mov ax, [window.width]
mov cx, [window.height]
sub cx, 2
shl cx, 1
mul cx
@ -986,6 +1010,22 @@ unhook_self_from_window_chain:
pop bx
ret
; ------------------------------------------------------------------
; Error handling
; ------------------------------------------------------------------
; in:
; si = window of error type
; out:
; clobbers si, di, cx
raise_error:
mov di, window
mov cx, window_struc.size
rep movsb
call request_redraw
ret
; ------------------------------------------------------------------
; Memory management
; ------------------------------------------------------------------
@ -1083,21 +1123,59 @@ cur_file_address: dw 0 ; Segment
beg_file_address dw 0
end_file_address dw 0
window:
.x dw 24
.y dw 9
.width dw FS_DIRENT_NAME_SIZE + 2
.height dw 6
.data_address dw filename_window_data
struc window_struc
.x resw 1
.y resw 1
.width resw 1
.height resw 1
.data_address resw 1
.size:
endstruc
filename_window:
.x dw 24
.y dw 9
.width dw FS_DIRENT_NAME_SIZE + 2
.height dw 6
.data_address dw filename_window_data
text_window:
.x dw 17
.y dw 7
.width dw 52
.height dw 16
.data_address dw text_window_data
oom_window:
.x dw 30
.y dw 10
.width dw 13
.height dw 2
.data_address dw oom_window_data
ood_window:
.x dw 36
.y dw 13
.width dw 17
.height dw 2
.data_address dw ood_window_data
window_next dw 0xffff
window_x dw 24
window_y dw 9
window_width dw FS_DIRENT_NAME_SIZE + 2
window_height dw 6
text_window_x dw 17
text_window_y dw 7
text_window_width dw 52
text_window_height dw 16
window_mouse_released_inside db 0
window_status db WINDOW_STATUS_NORMAL
window_move_x_offset dw 0
cur_filename_address dw filename_window_data.filename
file_opened db 0
; pre-built windows
CANCEL_COLOR equ 0x80
OK_COLOR equ 0x20
filename_window_data:
@ -1123,8 +1201,21 @@ filename_window_data:
; blank line
times FS_DIRENT_NAME_SIZE + 2 db 0, 0x70
cur_filename_address dw filename_window_data.filename
file_opened db 0
oom_window_data:
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
db ' ', 0xf0, 'm', 0xf0, 'e', 0xf0, 'm', 0xf0, 'o', 0xf0, 'r', 0xf0
db 'y', 0xf0
ood_window_data:
db 'E', 0x0f, 'r', 0x0f, 'r', 0x0f, 'o', 0x0f, 'r', 0x0f
times 17-5-1 db 0x00, 0x0f
db 'x', 0x0f
db 'O', 0xf0, 'u', 0xf0, 't', 0xf0, ' ', 0xf0, 'o', 0xf0, 'f', 0xf0
db ' ', 0xf0, 'd', 0xf0, 'i', 0xf0, 's', 0xf0, 'k', 0xf0, ' ', 0xf0
db 's', 0xf0, 'p', 0xf0, 'a', 0xf0, 'c', 0xf0, 'e', 0xf0
section .bss
text_window_data resw ROWS*COLUMNS