kolibrios/kernel/trunk/gui/window.inc

2551 lines
68 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
;==============================================================================
; public functions
;==============================================================================
window.BORDER_SIZE = 5
uglobal
common_colours rd 48
draw_limits RECT
endg
;------------------------------------------------------------------------------
align 4
syscall_draw_window: ; system function 0
mov eax, edx
shr eax, 24
and al, 0x0f
cmp al, 5
jae .exit
push eax
call window._.sys_set_window
pop eax
or al, al
jnz @f
; type I - original style
call drawwindow_I
jmp window._.draw_window_caption.2
;--------------------------------------
@@:
dec al
jnz @f
; type II - only reserve area, no draw
call __sys_draw_pointer
jmp .exit
;--------------------------------------
@@:
dec al
jnz @f
; type III - new style
call drawwindow_III
jmp window._.draw_window_caption.2
;--------------------------------------
@@:
; type IV & V - skinned window (resizable & not)
mov eax, [thread_count]
movzx eax, word[WIN_POS + eax * 2]
cmp eax, [current_slot_idx]
setz al
movzx eax, al
push eax
call drawwindow_IV
jmp window._.draw_window_caption.2
;--------------------------------------
.exit:
ret
;------------------------------------------------------------------------------
align 4
; system function 1
syscall_setpixel:
mov eax, ebx
mov ebx, ecx
mov ecx, edx
mov edx, [current_slot_idx]
shl edx, BSF sizeof.WDATA
add eax, [edx + window_data + WDATA.box.left]
add ebx, [edx + window_data + WDATA.box.top]
mov edi, [current_slot]
add eax, [edi+APPDATA.wnd_clientbox.left]
add ebx, [edi+APPDATA.wnd_clientbox.top]
xor edi, edi ; no force
and ecx, 0xFBFFFFFF ;negate 0x04000000 save to mouseunder area
jmp __sys_putpixel
;------------------------------------------------------------------------------
align 4
; system function 4
syscall_writetext:
push esi ;check pointer on kernel address.
test ecx, 0x80000000
jz @f
xor esi, esi
@@:
stdcall is_region_userspace, edx, esi
pop esi
jnz .err
mov eax, [current_slot_idx]
shl eax, BSF sizeof.WDATA
mov ebp, [eax + window_data + WDATA.box.left]
push esi
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
shl ebp, 16
add ebp, [eax + window_data + WDATA.box.top]
add bp, word[esi+APPDATA.wnd_clientbox.top]
pop esi
test ecx, 0x08000000 ; redirect the output to the user area
jnz @f
add ebx, ebp
align 4
@@:
mov eax, edi
test ecx, 0x08000000 ; redirect the output to the user area
jnz @f
xor edi, edi
jmp dtext
@@: ; check pointer
stdcall is_region_userspace, edi, 0
jnz .err
jmp dtext
.err:
ret
;------------------------------------------------------------------------------
align 4
; system function 13
syscall_drawrect:
mov edi, edx ; color + gradient
and edi, 0x80FFFFFF
test bx, bx ; x.size
je .drectr
test cx, cx ; y.size
je .drectr
mov eax, ebx ; bad idea
mov ebx, ecx
movzx ecx, ax ; ecx - x.size
shr eax, 16 ; eax - x.coord
movzx edx, bx ; edx - y.size
shr ebx, 16 ; ebx - y.coord
mov esi, [current_slot]
add eax, [esi + APPDATA.wnd_clientbox.left]
add ebx, [esi + APPDATA.wnd_clientbox.top]
add ecx, eax
add edx, ebx
jmp vesa20_drawbar
.drectr:
ret
;------------------------------------------------------------------------------
align 4
; system function 38
syscall_drawline:
mov edi, [current_slot_idx]
shl edi, BSF sizeof.WDATA
movzx eax, word[edi + window_data + WDATA.box.left]
mov ebp, eax
mov esi, [current_slot]
add ebp, [esi+APPDATA.wnd_clientbox.left]
add ax, word[esi+APPDATA.wnd_clientbox.left]
add ebp, ebx
shl eax, 16
movzx ebx, word[edi + window_data + WDATA.box.top]
add eax, ebp
mov ebp, ebx
add ebp, [esi+APPDATA.wnd_clientbox.top]
add bx, word[esi+APPDATA.wnd_clientbox.top]
add ebp, ecx
shl ebx, 16
xor edi, edi
add ebx, ebp
mov ecx, edx
jmp __sys_draw_line
;------------------------------------------------------------------------------
align 4
; system function 48
syscall_display_settings:
cmp ebx, 13
ja .ret
jmp dword[.ftable + ebx*4]
align 4
.ftable:
dd .redrawWholeScreen
dd .setButtonStyle
dd .setSystemColors
dd .getSystemColors
dd .getCaptionHeight
dd .getScreenWorkingArea
dd .setScreenWorkingArea
dd .getSkinMargins
dd .setSkin
dd .getFontSmoothing
dd .setFontSmoothing
dd .getFontSize
dd .setFontSize
dd .setSkinUnicode
.redrawWholeScreen:
xor eax, eax
inc ebx
cmp [windowtypechanged], ebx
jne .ret
mov [windowtypechanged], eax
.redrawScreen:
xor eax, eax
mov [draw_limits.left], eax
mov [draw_limits.top], eax
mov eax, [_display.width]
dec eax
mov [draw_limits.right], eax
mov eax, [_display.height]
dec eax
mov [draw_limits.bottom], eax
mov eax, window_data
jmp redrawscreen
.setButtonStyle:
; in: ecx: 0 = flat, 1 = with gradient
and ecx, 1
cmp ecx, [buttontype]
je .ret
mov [buttontype], ecx
mov [windowtypechanged], ebx
.ret:
ret
.setSystemColors:
; in: ecx = pointer to color table, edx = size of color table
dec ebx
mov esi, ecx
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
stdcall is_region_userspace, esi, edx ;
jz @f ;
ret ;
@@:
mov edi, common_colours
mov ecx, edx
rep movsb
mov [windowtypechanged], ebx
ret
.getSystemColors:
; in: ecx = pointer to color table, edx = size of color table
mov edi, ecx
cmp edx, 192
jnae @f
mov edx, 192 ; max size
@@:
stdcall is_region_userspace, edi, edx
jz @f
ret
@@:
mov esi, common_colours
mov ecx, edx
rep movsb
ret
.getCaptionHeight:
mov eax, [_skinh]
mov [esp + 32], eax
ret
.getScreenWorkingArea:
; out: eax = pack[left, right], ebx = pack[top, bottom]
mov eax, [screen_workarea.left - 2]
mov ax, word[screen_workarea.right]
mov [esp + SYSCALL_STACK.eax], eax
mov eax, [screen_workarea.top - 2]
mov ax, word[screen_workarea.bottom]
mov [esp + SYSCALL_STACK.ebx], eax
ret
.setScreenWorkingArea:
; in: ecx = pack[left, right], edx = pack[top, bottom]
xor esi, esi
mov edi, [_display.width]
dec edi
mov eax, ecx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_horizontal
inc esi
or eax, eax
jge @f
xor eax, eax
@@:
mov [screen_workarea.left], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@:
mov [screen_workarea.right], ebx
.check_horizontal:
mov edi, [_display.height]
dec edi
mov eax, edx
movsx ebx, ax
sar eax, 16
cmp eax, ebx
jge .check_if_redraw_needed
inc esi
or eax, eax
jge @f
xor eax, eax
@@:
mov [screen_workarea.top], eax
cmp ebx, edi
jle @f
mov ebx, edi
@@:
mov [screen_workarea.bottom], ebx
.check_if_redraw_needed:
or esi, esi
jz @f
call repos_windows
.calculateScreen:
xor eax, eax
xor ebx, ebx
mov ecx, [_display.width]
mov edx, [_display.height]
dec ecx
dec edx
jmp calculatescreen
.getSkinMargins:
; out: eax = pack[left, right], ebx = pack[top, bottom]
mov eax, [_skinmargins + 0]
mov [esp + SYSCALL_STACK.eax], eax
mov eax, [_skinmargins + 4]
mov [esp + SYSCALL_STACK.ebx], eax
ret
.setSkin:
; in: ecx -> file path string
mov ebx, ecx
call read_skin_file
mov [esp + SYSCALL_STACK.eax], eax
test eax, eax
jnz .ret
call .calculateScreen
jmp .redrawScreen
.getFontSmoothing:
xor eax, eax
mov al, [fontSmoothing]
mov [esp + SYSCALL_STACK.eax], eax
ret
.setFontSmoothing:
mov [fontSmoothing], cl
ret
.getFontSize:
xor eax, eax
mov al, [fontSize]
mov [esp + SYSCALL_STACK.eax], eax
ret
.setFontSize:
mov [fontSize], cl
ret
.setSkinUnicode:
; in: ecx -> file path string, edx = string encoding
push ecx edx
stdcall kernel_alloc, maxPathLength
mov edi, eax
pop eax esi
push edi
call getFullPath
test eax, eax
jz @f
mov ebx, [esp]
call read_skin_file
mov [esp + SYSCALL_STACK.eax + 4], eax
@@:
call kernel_free
call .calculateScreen
jmp .redrawScreen
;------------------------------------------------------------------------------
align 4
; system function 50
;; Set window shape address:
;> ebx = 0
;> ecx = shape data address
; --------------------------
;; Set window shape scale:
;> ebx = 1
;> ecx = scale power (resulting scale is 2^ebx)
syscall_set_window_shape:
mov edi, [current_slot]
test ebx, ebx
jne .shape_scale
mov [edi + APPDATA.wnd_shape], ecx
;--------------------------------------
align 4
.shape_scale:
dec ebx
jnz .exit
mov [edi + APPDATA.wnd_shape_scale], ecx
;--------------------------------------
align 4
.exit:
ret
;------------------------------------------------------------------------------
align 4
; system function 67
syscall_move_window:
mov edi, [current_slot_idx]
shl edi, BSF sizeof.WDATA
add edi, window_data
test [edi + WDATA.fl_wdrawn], 1
jz .exit
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .exit
cmp ebx, -1
jne @f
mov ebx, [edi + WDATA.box.left]
;--------------------------------------
align 4
@@:
cmp ecx, -1
jne @f
mov ecx, [edi + WDATA.box.top]
;--------------------------------------
align 4
@@:
cmp edx, -1
jne @f
mov edx, [edi + WDATA.box.width]
;--------------------------------------
align 4
@@:
cmp esi, -1
jne @f
mov esi, [edi + WDATA.box.height]
;--------------------------------------
align 4
@@:
push esi edx ecx ebx
mov eax, esp
mov bl, [edi + WDATA.fl_wstate]
;--------------------------------------
align 4
@@:
cmp [REDRAW_BACKGROUND], byte 0
jz @f
call change_task
jmp @b
;--------------------------------------
align 4
@@:
call window._.set_window_box
add esp, sizeof.BOX
.exit:
ret
;------------------------------------------------------------------------------
; system function 71
syscall_window_settings:
mov edi, [current_slot_idx]
shl edi, BSF sizeof.WDATA
or [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
cmp ebx, 2
jz @f
xor edx, edx
@@:
cmp dl, 4
jc @f
xor edx, edx
@@:
mov [edi*8 + SLOT_BASE + APPDATA.wnd_caption], ecx
mov [edi*8 + SLOT_BASE + APPDATA.captionEncoding], dl
jmp window._.draw_window_caption
;------------------------------------------------------------------------------
align 4
set_window_defaults:
mov byte [window_data + sizeof.WDATA + WDATA.cl_titlebar + 3], 1 ; desktop is not movable
push eax ecx
xor eax, eax
mov ecx, WIN_STACK
;--------------------------------------
align 4
@@:
inc eax
add ecx, 2
; process no
mov [ecx + 0x000], ax
; positions in stack
mov [ecx + 0x400], ax
cmp ecx, WIN_POS - 2
jne @b
pop ecx eax
ret
;------------------------------------------------------------------------------
align 4
;? Scan all windows from bottom to top, calling `setscreen` for each one
;? intersecting given screen area
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
calculatescreen:
push esi
pushfd
cli
mov esi, 1
call window._.set_screen
push ebp
mov ebp, [thread_count]
cmp ebp, 1
jbe .exit
push eax ;for num layout
push edx ecx ebx eax
mov dword[esp+10h], ZPOS_DESKTOP
;--------------------------------------
align 4
.layout:
mov esi, 1 ; = num in window stack
mov ebp, [thread_count]
;--------------------------------------
align 4
.next_window:
movzx edi, word[WIN_POS + esi * 2]
shl edi, BSF sizeof.WDATA ;size of TASKDATA and WDATA = 32 bytes
cmp byte [SLOT_BASE + edi*8 + APPDATA.state], TSTATE_FREE
je .skip_window
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_window
mov eax, [esp+10h]
cmp [edi + WDATA.z_modif], al
jne .skip_window
mov eax, [edi + WDATA.box.left]
cmp eax, [esp + RECT.right]
jg .skip_window
mov ebx, [edi + WDATA.box.top]
cmp ebx, [esp + RECT.bottom]
jg .skip_window
mov ecx, [edi + WDATA.box.width]
add ecx, eax
cmp ecx, [esp + RECT.left]
jl .skip_window
mov edx, [edi + WDATA.box.height]
add edx, ebx
cmp edx, [esp + RECT.top]
jl .skip_window
cmp eax, [esp + RECT.left]
jae @f
mov eax, [esp + RECT.left]
;--------------------------------------
align 4
@@:
cmp ebx, [esp + RECT.top]
jae @f
mov ebx, [esp + RECT.top]
;--------------------------------------
align 4
@@:
cmp ecx, [esp + RECT.right]
jbe @f
mov ecx, [esp + RECT.right]
;--------------------------------------
align 4
@@:
cmp edx, [esp + RECT.bottom]
jbe @f
mov edx, [esp + RECT.bottom]
;--------------------------------------
align 4
@@:
push esi
movzx esi, word[WIN_POS + esi * 2]
call window._.set_screen
pop esi
;--------------------------------------
align 4
.skip_window:
inc esi
dec ebp
jnz .next_window
;---------------------------------------------
inc dword[esp+10h]
cmp dword[esp+10h], ZPOS_ALWAYS_TOP
jle .layout
;---------------------------------------------
mov esi, [thread_count]
movzx edi, word[WIN_POS + esi * 2]
shl edi, BSF sizeof.WDATA
add edi, window_data
pop eax ebx ecx edx
pop ebp ;del num layout
;--------------------------------------
align 4
.exit:
pop ebp
inc [_display.mask_seqno]
popfd
pop esi
ret
;------------------------------------------------------------------------------
align 4
repos_windows:
mov ecx, [thread_count]
mov edi, window_data + sizeof.WDATA * 2
call force_redraw_background
dec ecx
jle .exit
;--------------------------------------
align 4
.next_window:
mov [edi + WDATA.fl_redraw], 1
test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
jnz .fix_maximized
mov eax, [edi + WDATA.box.left]
add eax, [edi + WDATA.box.width]
mov ebx, [_display.width]
cmp eax, ebx
jl .fix_vertical
mov eax, [edi + WDATA.box.width]
sub eax, ebx
jl @f
mov [edi + WDATA.box.width], ebx
;--------------------------------------
align 4
@@:
sub ebx, [edi + WDATA.box.width]
mov [edi + WDATA.box.left], ebx
;--------------------------------------
align 4
.fix_vertical:
mov eax, [edi + WDATA.box.top]
add eax, [edi + WDATA.box.height]
mov ebx, [_display.height]
cmp eax, ebx
jl .fix_client_box
mov eax, [edi + WDATA.box.height]
sub eax, ebx
jl @f
mov [edi + WDATA.box.height], ebx
;--------------------------------------
align 4
@@:
sub ebx, [edi + WDATA.box.height]
mov [edi + WDATA.box.top], ebx
;--------------------------------------
align 4
.fix_client_box:
call window._.set_window_clientbox
add edi, sizeof.WDATA
loop .next_window
;--------------------------------------
align 4
.exit:
ret
;--------------------------------------
align 4
.fix_maximized:
mov eax, [screen_workarea.left]
mov [edi + WDATA.box.left], eax
sub eax, [screen_workarea.right]
neg eax
mov [edi + WDATA.box.width], eax
mov eax, [screen_workarea.top]
mov [edi + WDATA.box.top], eax
test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
jnz .fix_client_box
sub eax, [screen_workarea.bottom]
neg eax
mov [edi + WDATA.box.height], eax
jmp .fix_client_box
;------------------------------------------------------------------------------
align 4
;> eax = pack[16(left), 16(right)]
;> ebx = pack[16(top), 16(bottom)]
;> esi = color
; ?? RR GG BB ; 0x01000000 negation
; ; 0x02000000 used for draw_rectangle without top line
; ; for example drawwindow_III and drawwindow_IV
draw_rectangle:
push eax ebx ecx edi
xor edi, edi
;--------------------------------------
align 4
.flags_set:
push ebx
; set line color
mov ecx, esi
; draw top border
rol ebx, 16
push ebx
rol ebx, 16
pop bx
test ecx, 1 shl 25
jnz @f
sub ecx, 1 shl 25
; call [draw_line]
call __sys_draw_line
;--------------------------------------
align 4
@@:
; draw bottom border
mov ebx, [esp - 2]
pop bx
; call [draw_line]
call __sys_draw_line
pop ebx
add ebx, 1 * 65536 - 1
; draw left border
rol eax, 16
push eax
rol eax, 16
pop ax
; call [draw_line]
call __sys_draw_line
; draw right border
mov eax, [esp - 2]
pop ax
; call [draw_line]
call __sys_draw_line
pop edi ecx ebx eax
ret
;--------------------------------------
align 4
.forced:
push eax ebx ecx edi
xor edi, edi
inc edi
jmp .flags_set
;------------------------------------------------------------------------------
align 4
drawwindow_I_caption:
push [edx + WDATA.cl_titlebar]
mov esi, edx
mov edx, [esi + WDATA.box.top]
mov eax, edx
lea ebx, [edx + 21]
inc edx
add eax, [esi + WDATA.box.height]
cmp ebx, eax
jbe @f
mov ebx, eax
;--------------------------------------
align 4
@@:
push ebx
xor edi, edi
;--------------------------------------
align 4
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
inc eax
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
dec eax
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
mov [esi + WDATA.cl_titlebar], ecx
;--------------------------------------
align 4
@@:
and ecx, 0x00ffffff
; call [draw_line]
call __sys_draw_line
inc edx
cmp edx, [esp]
jb .next_line
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
;------------------------------------------------------------------------------
align 4
drawwindow_I:
pushad
; window border
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
mov esi, [edx + WDATA.cl_frames]
call draw_rectangle
; window caption
call drawwindow_I_caption
; window client area
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
; does client area have a positive size on screen?
cmp [esi + WDATA.box.height], 21
jle .exit
; okay, let's draw it
mov eax, 1
mov ebx, 21
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
; call [drawbar]
call vesa20_drawbar
;--------------------------------------
align 4
.exit:
popad
ret
;------------------------------------------------------------------------------
align 4
drawwindow_III_caption:
mov ecx, [edx + WDATA.cl_titlebar]
push ecx
mov esi, edx
mov edx, [esi + WDATA.box.top]
add edx, 4
mov ebx, [esi + WDATA.box.top]
add ebx, 20
mov eax, [esi + WDATA.box.top]
add eax, [esi + WDATA.box.height]
cmp ebx, eax
jb @f
mov ebx, eax
;--------------------------------------
align 4
@@:
push ebx
xor edi, edi
;--------------------------------------
align 4
.next_line:
mov ebx, edx
shl ebx, 16
add ebx, edx
mov eax, [esi + WDATA.box.left]
shl eax, 16
add eax, [esi + WDATA.box.left]
add eax, [esi + WDATA.box.width]
add eax, 4 * 65536 - 4
mov ecx, [esi + WDATA.cl_titlebar]
test ecx, 0x40000000
jz @f
add ecx, 0x00040404
;--------------------------------------
align 4
@@:
test ecx, 0x80000000
jz @f
sub ecx, 0x00040404
;--------------------------------------
align 4
@@:
mov [esi + WDATA.cl_titlebar], ecx
and ecx, 0x00ffffff
; call [draw_line]
call __sys_draw_line
inc edx
cmp edx, [esp]
jb .next_line
add esp, 4
pop [esi + WDATA.cl_titlebar]
ret
;------------------------------------------------------------------------------
align 4
drawwindow_III:
pushad
; window border
mov eax, [edx + WDATA.box.left - 2]
mov ax, word[edx + WDATA.box.left]
add ax, word[edx + WDATA.box.width]
mov ebx, [edx + WDATA.box.top - 2]
mov bx, word[edx + WDATA.box.top]
add bx, word[edx + WDATA.box.height]
mov esi, [edx + WDATA.cl_frames]
shr esi, 1
and esi, 0x007f7f7f
call draw_rectangle
push esi
mov ecx, 3
mov esi, [edx + WDATA.cl_frames]
;--------------------------------------
align 4
.next_frame:
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
dec ecx
jnz .next_frame
pop esi
add eax, 1 * 65536 - 1
add ebx, 1 * 65536 - 1
call draw_rectangle
; window caption
call drawwindow_III_caption
; window client area
; do we need to draw it?
mov edi, [esi + WDATA.cl_workarea]
test edi, 0x40000000
jnz .exit
; does client area have a positive size on screen?
mov edx, [esi + WDATA.box.top]
add edx, 21 + 5
mov ebx, [esi + WDATA.box.top]
add ebx, [esi + WDATA.box.height]
cmp edx, ebx
jg .exit
; okay, let's draw it
mov eax, 5
mov ebx, 20
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
sub ecx, 4
sub edx, 4
; call [drawbar]
call vesa20_drawbar
;--------------------------------------
align 4
.exit:
popad
ret
;------------------------------------------------------------------------------
align 4
;? Activate window, redrawing if necessary
waredraw:
push -1
mov eax, [thread_count]
lea eax, [WIN_POS + eax * 2]
cmp eax, esi
pop eax
je .exit
; is it overlapped by another window now?
push ecx
call window._.check_window_draw
test ecx, ecx
pop ecx
jz .do_not_draw
; yes it is, activate and update screen buffer
call window._.window_activate
pushad
mov edi, [thread_count]
movzx esi, word[WIN_POS + edi * 2]
shl esi, BSF sizeof.WDATA
add esi, window_data
mov eax, [esi + WDATA.box.left]
mov ebx, [esi + WDATA.box.top]
mov ecx, [esi + WDATA.box.width]
mov edx, [esi + WDATA.box.height]
add ecx, eax
add edx, ebx
mov edi, [thread_count]
movzx esi, word[WIN_POS + edi * 2]
call window._.set_screen
call window._.set_top_wnd
inc [_display.mask_seqno]
popad
; tell application to redraw itself
mov [edi + WDATA.fl_redraw], 1
xor eax, eax
jmp .exit
;--------------------------------------
align 4
.do_not_draw:
; no it's not, just activate the window
call window._.window_activate
xor eax, eax
ret
;--------------------------------------
align 4
.exit:
inc eax
ret
;------------------------------------------------------------------------------
align 4
minimize_all_window:
push ebx ecx edx esi edi
pushfd
cli
xor edx, edx
mov eax, 2 ; we do not minimize the kernel thread N1
mov ebx, [thread_count]
;--------------------------------------
align 4
.loop:
movzx edi, word[WIN_POS + eax * 2]
shl edi, BSF sizeof.WDATA
; it is a unused slot?
cmp byte [SLOT_BASE + edi*8 + APPDATA.state], TSTATE_FREE
je @f
; it is a hidden thread?
lea esi, [SLOT_BASE + edi*8 + APPDATA.app_name]
cmp [esi], byte '@'
je @f
; is it already minimized?
test [edi + window_data+WDATA.fl_wstate], WSTATE_MINIMIZED
jnz @f
; no it's not, let's do that
or [edi + window_data+WDATA.fl_wstate], WSTATE_MINIMIZED
inc edx
;--------------------------------------
align 4
@@:
inc eax
cmp eax, ebx
jbe .loop
; If nothing has changed
test edx, edx
jz @f
push edx
call syscall_display_settings.calculateScreen
call syscall_display_settings.redrawScreen
pop edx
;--------------------------------------
align 4
@@:
mov eax, edx
popfd
pop edi esi edx ecx ebx
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
;> eax = window number on screen
;# corrupts [dl*]
minimize_window:
push edi
pushfd
cli
; is it already minimized?
movzx edi, word[WIN_POS + eax * 2]
shl edi, BSF sizeof.WDATA
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .exit
push eax ebx ecx edx esi
; no it's not, let's do that
or [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
; If the window width is 0, then the action is not needed.
cmp [edi + WDATA.box.width], dword 0
je @f
; If the window height is 0, then the action is not needed.
cmp [edi + WDATA.box.height], dword 0
je @f
mov eax, [edi + WDATA.box.left]
mov [draw_limits.left], eax
mov ecx, eax
add ecx, [edi + WDATA.box.width]
mov [draw_limits.right], ecx
mov ebx, [edi + WDATA.box.top]
mov [draw_limits.top], ebx
mov edx, ebx
add edx, [edi + WDATA.box.height]
mov [draw_limits.bottom], edx
; DEBUGF 1, "K : minimize_window\n"
; DEBUGF 1, "K : dl_left %x\n",[draw_limits.left]
; DEBUGF 1, "K : dl_right %x\n",[draw_limits.right]
; DEBUGF 1, "K : dl_top %x\n",[draw_limits.top]
; DEBUGF 1, "K : dl_bottom %x\n",[draw_limits.bottom]
call calculatescreen
; xor esi, esi
; xor eax, eax
mov eax, edi
call redrawscreen
;--------------------------------------
align 4
@@:
pop esi edx ecx ebx eax
;--------------------------------------
align 4
.exit:
popfd
pop edi
ret
;------------------------------------------------------------------------------
align 4
;> eax = window number on screen
;# corrupts [dl*]
restore_minimized_window:
pushad
pushfd
cli
; is it already restored?
movzx esi, word[WIN_POS + eax * 2]
mov edi, esi
shl edi, BSF sizeof.WDATA
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jz .exit
; no it's not, let's do that
mov [edi + WDATA.fl_redraw], 1
and [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
mov ebp, window._.set_screen
cmp eax, [thread_count]
jz @f
mov ebp, calculatescreen
;--------------------------------------
align 4
@@:
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call ebp
cmp ebp, window._.set_screen
jne @f
call window._.set_top_wnd
@@:
inc [_display.mask_seqno]
;--------------------------------------
align 4
.exit:
popfd
popad
ret
;------------------------------------------------------------------------------
align 4
; TODO: remove this proc
;------------------------------------------------------------------------------
window_check_events:
; do we have window minimize/restore request?
cmp [window_minimize], 0
je .exit
; okay, minimize or restore top-most window and exit
mov eax, [thread_count]
mov bl, 0
xchg [window_minimize], bl
dec bl
jnz @f
call minimize_window
jmp .exit
;--------------------------------------
align 4
@@:
call restore_minimized_window
;--------------------------------------
align 4
.exit:
ret
;------------------------------------------------------------------------------
align 4
;> esi = process slot
sys_window_maximize_handler:
mov edi, esi
shl edi, BSF sizeof.WDATA
add edi, window_data
; can window change its height?
; only types 2 and 3 can be resized
mov dl, [edi + WDATA.fl_wstyle]
test dl, 2
jz .exit
; toggle normal/maximized window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_MAXIMIZED
; calculate and set appropriate window bounds
test bl, WSTATE_MAXIMIZED
jz .restore_size
mov eax, [screen_workarea.left]
mov ecx, [screen_workarea.top]
push [screen_workarea.bottom] \
[screen_workarea.right] \
ecx \
eax
sub [esp + BOX.width], eax
sub [esp + BOX.height], ecx
mov eax, esp
jmp .set_box
;--------------------------------------
align 4
.restore_size:
mov eax, esi
shl eax, BSF sizeof.APPDATA
add eax, SLOT_BASE + APPDATA.saved_box
push [eax + BOX.height] \
[eax + BOX.width] \
[eax + BOX.top] \
[eax + BOX.left]
mov eax, esp
;--------------------------------------
align 4
.set_box:
test bl, WSTATE_ROLLEDUP
jz @f
xchg eax, ecx
call window._.get_rolledup_height
mov [ecx + BOX.height], eax
xchg eax, ecx
;--------------------------------------
align 4
@@:
call window._.set_window_box
add esp, sizeof.BOX
;--------------------------------------
align 4
.exit:
inc [_display.mask_seqno]
ret
;------------------------------------------------------------------------------
align 4
;> esi = process slot
sys_window_rollup_handler:
mov edx, esi
shl edx, BSF sizeof.APPDATA
add edx, SLOT_BASE
; toggle normal/rolled up window state
mov bl, [edi + WDATA.fl_wstate]
xor bl, WSTATE_ROLLEDUP
; calculate and set appropriate window bounds
test bl, WSTATE_ROLLEDUP
jz .restore_size
call window._.get_rolledup_height
push eax \
[edi + WDATA.box.width] \
[edi + WDATA.box.top] \
[edi + WDATA.box.left]
mov eax, esp
jmp .set_box
;--------------------------------------
align 4
.restore_size:
test bl, WSTATE_MAXIMIZED
jnz @f
add esp, -sizeof.BOX
lea eax, [edx + APPDATA.saved_box]
jmp .set_box
;--------------------------------------
align 4
@@:
mov eax, [screen_workarea.top]
push [screen_workarea.bottom] \
[edi + WDATA.box.width] \
eax \
[edi + WDATA.box.left]
sub [esp + BOX.height], eax
mov eax, esp
;--------------------------------------
align 4
.set_box:
call window._.set_window_box
add esp, sizeof.BOX
ret
;------------------------------------------------------------------------------
align 4
;------------------------------------------------------------------------------
;sys_window_start_moving_handler:
;------------------------------------------------------------------------------
;? <description>
;------------------------------------------------------------------------------
;> eax = old (original) window box
;> esi = process slot
;------------------------------------------------------------------------------
; mov edi, eax
; call window._.draw_negative_box
; ret
;------------------------------------------------------------------------------
align 4
;> eax = old (original) window box
;> ebx = new (final) window box
;> esi = process slot
sys_window_end_moving_handler:
; mov edi, ebx
; call window._.end_moving__box
mov edi, esi
shl edi, BSF sizeof.WDATA
add edi, window_data
test [fl_moving], 1
jz @f
push edi
mov edi, ebx
call window._.draw_negative_box
pop edi
@@:
mov eax, ebx
mov bl, [edi + WDATA.fl_wstate]
call window._.set_window_box
ret
;------------------------------------------------------------------------------
align 4
;> eax = old (from previous call) window box
;> ebx = new (current) window box
;> esi = process_slot
sys_window_moving_handler:
mov edi, eax
call window._.draw_negative_box
mov edi, ebx
call window._.draw_negative_box
ret
;==============================================================================
; private functions
;==============================================================================
iglobal
align 4
window_topleft dd \
1, 21, \ ;type 0
0, 0, \ ;type 1
5, 20, \ ;type 2
5, ?, \ ;type 3 {set by skin}
5, ? ;type 4 {set by skin}
endg
;------------------------------------------------------------------------------
align 4
;> eax = old (original) window box
;> ebx = new (final) window box
;> edi = pointer to WDATA struct
window._.invalidate_screen:
push eax ebx
; TODO: do we really need `draw_limits`?
; Yes, they are used by background drawing code.
; we need only to restore the background windows at the old place!
mov ecx, [ebx + BOX.left]
mov [draw_limits.left], ecx
add ecx, [ebx + BOX.width]
mov [draw_limits.right], ecx
mov ecx, [ebx + BOX.top]
mov [draw_limits.top], ecx
add ecx, [ebx + BOX.height]
mov [draw_limits.bottom], ecx
; recalculate screen buffer at old position
push ebx
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
pop eax
; recalculate screen buffer at new position
mov edx, [eax + BOX.height]
mov ecx, [eax + BOX.width]
mov ebx, [eax + BOX.top]
mov eax, [eax + BOX.left]
add ecx, eax
add edx, ebx
call calculatescreen
mov eax, edi
call redrawscreen
; tell window to redraw itself
mov [edi + WDATA.fl_redraw], 1
pop ebx eax
ret
;------------------------------------------------------------------------------
align 4
;> eax = pointer to BOX struct
;> bl = new window state flags
;> edi = pointer to WDATA struct
window._.set_window_box:
push eax ebx esi
; don't do anything if the new box is identical to the old
cmp bl, [edi + WDATA.fl_wstate]
jnz @f
mov esi, eax
push edi
if WDATA.box
add edi, WDATA.box
end if
mov ecx, 4
repz cmpsd
pop edi
jz .exit
;--------------------------------------
align 4
@@:
add esp, -sizeof.BOX
mov ebx, esp
if WDATA.box
lea esi, [edi + WDATA.box]
else
mov esi, edi ; optimization for WDATA.box = 0
end if
xchg eax, esi
mov ecx, sizeof.BOX
call memmove
xchg eax, esi
xchg ebx, esi
call memmove
mov eax, ebx
mov ebx, esi
call window._.check_window_position
call window._.set_window_clientbox
call window._.invalidate_screen
add esp, sizeof.BOX
mov cl, [esp + 4]
mov ch, cl
xchg cl, [edi + WDATA.fl_wstate]
or cl, ch
test cl, WSTATE_MAXIMIZED
jnz .exit
mov eax, edi
sub eax, window_data
shl eax, 3
add eax, SLOT_BASE
lea ebx, [edi + WDATA.box]
xchg esp, ebx
pop [eax + APPDATA.saved_box.left] \
[eax + APPDATA.saved_box.top] \
[eax + APPDATA.saved_box.width] \
edx
xchg esp, ebx
test ch, WSTATE_ROLLEDUP
jnz .exit
mov [eax + APPDATA.saved_box.height], edx
;--------------------------------------
align 4
.exit:
pop esi ebx eax
ret
;------------------------------------------------------------------------------
align 4
;> edi = pointer to WDATA struct
window._.set_window_clientbox:
push eax ecx edi
mov eax, [_skinh]
mov [window_topleft + 8 * 3 + 4], eax
mov [window_topleft + 8 * 4 + 4], eax
mov ecx, edi
sub edi, window_data
shl edi, 3
test [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE
jz .whole_window
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
mov eax, [eax * 8 + window_topleft + 0]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
shl eax, 1
neg eax
add eax, [ecx + WDATA.box.width]
inc eax ;Leency: as window is created width+1 so client the same
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
movzx eax, [ecx + WDATA.fl_wstyle]
and eax, 0x0F
push [eax * 8 + window_topleft + 0]
mov eax, [eax * 8 + window_topleft + 4]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
neg eax
sub eax, [esp]
add eax, [ecx + WDATA.box.height]
inc eax ;Leency: as window is created height+1 so client the same
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
add esp, 4
jmp .exit
;--------------------------------------
align 4
.whole_window:
xor eax, eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
mov eax, [ecx + WDATA.box.width]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
mov eax, [ecx + WDATA.box.height]
mov [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
;--------------------------------------
align 4
.exit:
pop edi ecx eax
ret
;------------------------------------------------------------------------------
align 4
;< edx = pointer to WDATA struct
window._.sys_set_window:
mov eax, [current_slot_idx]
shl eax, BSF sizeof.WDATA
add eax, window_data
; save window colors
mov [eax + WDATA.cl_workarea], edx
mov [eax + WDATA.cl_titlebar], esi
mov [eax + WDATA.cl_frames], edi
mov edi, eax
; Was it already defined before?
test [edi + WDATA.fl_wdrawn], 1
jnz .set_client_box
; No, it wasn't. After first draw_window we need redraw mouse necessarily!
; Otherwise the user can see cursor specified by f.37.5 from another window.
; He will be really unhappy! Usually, he will be enraged!
or [edi + WDATA.fl_wdrawn], 1
mov [redrawmouse_unconditional], 1
call wakeup_osloop
; performing initial window definition
movzx eax, bx
mov [edi + WDATA.box.width], eax
movzx eax, cx
mov [edi + WDATA.box.height], eax
sar ebx, 16
sar ecx, 16
mov [edi + WDATA.box.left], ebx
mov [edi + WDATA.box.top], ecx
call window._.check_window_position
push ecx edi
mov cl, [edi + WDATA.fl_wstyle]
mov eax, [edi + WDATA.cl_frames]
sub edi, window_data
shl edi, 3
add edi, SLOT_BASE
and cl, 0x0F
cmp cl, 3
je @f
cmp cl, 4
je @f
xor eax, eax
;--------------------------------------
align 4
@@:
mov [edi + APPDATA.wnd_caption], eax
mov esi, [esp]
add edi, APPDATA.saved_box
movsd
movsd
movsd
movsd
pop edi ecx
mov esi, [current_slot_idx]
movzx esi, word[WIN_STACK + esi * 2]
lea esi, [WIN_POS + esi * 2]
call waredraw
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
add ecx, eax
add edx, ebx
call calculatescreen
mov byte[KEY_COUNT], 0 ; empty keyboard buffer
mov byte[BTN_COUNT], 0 ; empty button buffer
;--------------------------------------
align 4
.set_client_box:
; update window client box coordinates
call window._.set_window_clientbox
; reset window redraw flag and exit
mov [edi + WDATA.fl_redraw], 0
mov edx, edi
ret
;------------------------------------------------------------------------------
align 4
;? Check if window is inside screen area
;> edi = pointer to WDATA
window._.check_window_position:
push eax ebx ecx edx esi
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.top]
mov ecx, [edi + WDATA.box.width]
mov edx, [edi + WDATA.box.height]
mov esi, [_display.width]
cmp ecx, esi
jae .fix_width_high
;--------------------------------------
align 4
.check_left:
or eax, eax
jl .fix_left_low
add eax, ecx
cmp eax, esi
jge .fix_left_high
;--------------------------------------
align 4
.check_height:
mov esi, [_display.height]
cmp edx, esi
jae .fix_height_high
;--------------------------------------
align 4
.check_top:
or ebx, ebx
jl .fix_top_low
add ebx, edx
cmp ebx, esi
jge .fix_top_high
;--------------------------------------
align 4
.exit:
pop esi edx ecx ebx eax
ret
;--------------------------------------
align 4
.fix_width_high:
mov ecx, esi
dec ecx
mov [edi + WDATA.box.width], ecx
jmp .check_left
;--------------------------------------
align 4
.fix_left_low:
xor eax, eax
mov [edi + WDATA.box.left], eax
jmp .check_height
;--------------------------------------
align 4
.fix_left_high:
mov eax, esi
sub eax, ecx
dec eax
mov [edi + WDATA.box.left], eax
jmp .check_height
;--------------------------------------
align 4
.fix_height_high:
mov edx, esi
dec edx
mov [edi + WDATA.box.height], edx
jmp .check_top
;--------------------------------------
align 4
.fix_top_low:
xor ebx, ebx
mov [edi + WDATA.box.top], ebx
jmp .exit
;--------------------------------------
align 4
.fix_top_high:
mov ebx, esi
sub ebx, edx
dec ebx
mov [edi + WDATA.box.top], ebx
jmp .exit
;------------------------------------------------------------------------------
align 4
;> edi = pointer to WDATA
window._.get_titlebar_height:
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jne @f
mov eax, [_skinh]
ret
;--------------------------------------
align 4
@@:
mov eax, 21
ret
;------------------------------------------------------------------------------
align 4
;> edi = pointer to WDATA
window._.get_rolledup_height:
mov al, [edi + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
jb @f
mov eax, [_skinh]
add eax, 3
ret
;--------------------------------------
align 4
@@:
or al, al
jnz @f
mov eax, 21
ret
;--------------------------------------
align 4
@@:
mov eax, 21 + 2
ret
;------------------------------------------------------------------------------
align 4
;? Reserve window area in screen buffer
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
window._.set_screen:
virtual at esp
ff_x dd ?
ff_y dd ?
ff_width dd ?
ff_xsz dd ?
ff_ysz dd ?
ff_scale dd ?
end virtual
pushad
cmp esi, 1
jz .check_for_shaped_window
mov edi, esi
shl edi, BSF sizeof.WDATA
cmp [window_data + edi + WDATA.box.width], 0
jnz .check_for_shaped_window
cmp [window_data + edi + WDATA.box.height], 0
jz .exit
;--------------------------------------
align 4
.check_for_shaped_window:
mov edi, esi
shl edi, BSF sizeof.APPDATA
add edi, SLOT_BASE
cmp [edi + APPDATA.wnd_shape], 0
jne .shaped_window
; get x&y size
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
; get WinMap start
push esi
mov esi, [_display.width]
mov edi, [d_width_calc_area + ebx*4]
add edi, eax
add edi, [_display.win_map]
pop eax
mov ah, al
push ax
shl eax, 16
pop ax
;--------------------------------------
align 4
.next_line:
push ecx
shr ecx, 2
rep stosd
mov ecx, [esp]
and ecx, 3
rep stosb
pop ecx
add edi, esi
sub edi, ecx
dec edx
jnz .next_line
jmp .exit
;--------------------------------------
align 4
.shaped_window:
; for (y=0; y <= x_size; y++)
; for (x=0; x <= x_size; x++)
; if (shape[coord(x,y,scale)]==1)
; set_pixel(x, y, process_number);
sub ecx, eax
sub edx, ebx
inc ecx
inc edx
push [edi + APPDATA.wnd_shape_scale] ; push scale first -> for loop
; get WinMap start -> ebp
push eax
mov eax, [d_width_calc_area + ebx*4]
add eax, [esp]
add eax, [_display.win_map]
mov ebp, eax
mov edi, [edi + APPDATA.wnd_shape]
pop eax
; eax = x_start
; ebx = y_start
; ecx = x_size
; edx = y_size
; esi = process_number
; edi = &shape
; [scale]
push edx ecx ; for loop - x,y size
mov ecx, esi
shl ecx, BSF sizeof.WDATA
mov edx, [window_data + ecx + WDATA.box.top]
push [window_data + ecx + WDATA.box.width] ; for loop - width
mov ecx, [window_data + ecx + WDATA.box.left]
sub ebx, edx
sub eax, ecx
push ebx eax ; for loop - x,y
add [ff_xsz], eax
add [ff_ysz], ebx
mov ebx, [ff_y]
;--------------------------------------
align 4
.ff_new_y:
mov edx, [ff_x]
;--------------------------------------
align 4
.ff_new_x:
; -- body --
mov ecx, [ff_scale]
mov eax, [ff_width]
inc eax
shr eax, cl
push ebx edx
shr ebx, cl
shr edx, cl
imul eax, ebx
add eax, edx
pop edx ebx
add eax, edi
call .read_byte
test al, al
jz @f
mov eax, esi
mov [ebp], al
; -- end body --
;--------------------------------------
align 4
@@:
inc ebp
inc edx
cmp edx, [ff_xsz]
jb .ff_new_x
sub ebp, [ff_xsz]
add ebp, [ff_x]
add ebp, [_display.width] ; screen.x
inc ebx
cmp ebx, [ff_ysz]
jb .ff_new_y
add esp, 24
;--------------------------------------
align 4
.exit:
popad
inc [_display.mask_seqno]
ret
;--------------------------------------
align 4
.read_byte:
; eax - address
; esi - slot
push eax ecx edx esi
xchg eax, esi
lea ecx, [esp + 12]
mov edx, 1
call read_process_memory
pop esi edx ecx eax
ret
;------------------------------------------------------------------------------
align 4
; Activate window
; esi = pointer to WIN_POS+ window data
window._.window_activate:
push eax ebx
; if type of current active window is 3 or 4, it must be redrawn
mov ebx, [thread_count]
; DEBUGF 1, "K : thread_count (0x%x)\n", ebx
movzx ebx, word[WIN_POS + ebx * 2]
shl ebx, BSF sizeof.WDATA
add eax, window_data
mov al, [window_data + ebx + WDATA.fl_wstyle]
and al, 0x0f
cmp al, 0x03
je .set_window_redraw_flag
cmp al, 0x04
jne .move_others_down
;--------------------------------------
align 4
.set_window_redraw_flag:
mov [window_data + ebx + WDATA.fl_redraw], 1
;--------------------------------------
align 4
.move_others_down:
; bx <- process no
movzx ebx, word[esi]
; bx <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
; drop others
xor eax, eax
;--------------------------------------
align 4
.next_stack_window:
cmp eax, [thread_count]
jae .move_self_up
inc eax
; push ebx
; xor ebx,ebx
; mov bx,[WIN_STACK + eax * 2]
; DEBUGF 1, "K : DEC WIN_STACK (0x%x)\n",ebx
; pop ebx
cmp [WIN_STACK + eax * 2], bx
jbe .next_stack_window
dec word[WIN_STACK + eax * 2]
jmp .next_stack_window
;--------------------------------------
align 4
.move_self_up:
movzx ebx, word[esi]
; number of thread
mov ax, word [thread_count]
; this is the last (and the upper)
mov [WIN_STACK + ebx * 2], ax
; update on screen - window stack
xor eax, eax
;--------------------------------------
align 4
.next_window_pos:
cmp eax, [thread_count]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
;--------------------------------------
align 4
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
pop ebx eax
ret
;------------------------------------------------------------------------------
; Deactivate window
; esi = pointer to WIN_POS+ window data
window._.window_deactivate:
push eax ebx
;--------------------------------------
align 4
.move_others_up:
; ax <- process no
movzx ebx, word[esi]
; ax <- position in window stack
movzx ebx, word[WIN_STACK + ebx * 2]
; up others
xor eax, eax
;--------------------------------------
align 4
.next_stack_window:
cmp eax, [thread_count]
jae .move_self_down
inc eax
cmp [WIN_STACK + eax * 2], bx
jae .next_stack_window
inc word[WIN_STACK + eax * 2]
jmp .next_stack_window
;--------------------------------------
align 4
.move_self_down:
movzx ebx, word[esi]
; this is the last (and the low)
mov [WIN_STACK + ebx * 2], word 1
; update on screen - window stack
xor eax, eax
;--------------------------------------
align 4
.next_window_pos:
cmp eax, [thread_count]
jae .reset_vars
inc eax
movzx ebx, word[WIN_STACK + eax * 2]
mov [WIN_POS + ebx * 2], ax
jmp .next_window_pos
;--------------------------------------
align 4
.reset_vars:
mov byte[KEY_COUNT], 0
mov byte[BTN_COUNT], 0
mov word[MOUSE_SCROLL_H], 0
mov word[MOUSE_SCROLL_V], 0
pop ebx eax
ret
;------------------------------------------------------------------------------
align 4
; Check if window is necessary to draw
; edi = pointer to WDATA
window._.check_window_draw:
mov cl, [edi + WDATA.fl_wstyle]
and cl, 0x0f
cmp cl, 3
je .exit.redraw ; window type 3
cmp cl, 4
je .exit.redraw ; window type 4
push eax ebx edx esi
mov eax, edi
sub eax, window_data
shr eax, 5
movzx eax, word[WIN_STACK + eax * 2] ; get value of the curr process
lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400
;--------------------------------------
align 4
.next_window:
add esi, 2
mov eax, [thread_count]
lea eax, word[WIN_POS + eax * 2] ; number of the upper window
cmp esi, eax
ja .exit.no_redraw
movzx edx, word[esi]
shl edx, BSF sizeof.WDATA ; size of TASKDATA and WDATA is 32 bytes
cmp byte [SLOT_BASE + edx*8 - sizeof.APPDATA + APPDATA.state], TSTATE_FREE
je .next_window
mov eax, [edi + WDATA.box.top]
mov ebx, [edi + WDATA.box.height]
add ebx, eax
mov ecx, [window_data + edx + WDATA.box.top]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.height]
cmp eax, ecx
jge .next_window
mov eax, [edi + WDATA.box.left]
mov ebx, [edi + WDATA.box.width]
add ebx, eax
mov ecx, [window_data + edx + WDATA.box.left]
cmp ecx, ebx
jge .next_window
add ecx, [window_data + edx + WDATA.box.width]
cmp eax, ecx
jge .next_window
pop esi edx ebx eax
;--------------------------------------
align 4
.exit.redraw:
xor ecx, ecx
inc ecx
ret
;--------------------------------------
align 4
.exit.no_redraw:
pop esi edx ebx eax
xor ecx, ecx
ret
;------------------------------------------------------------------------------
align 4
window._.draw_window_caption:
xor eax, eax
mov edx, [thread_count]
movzx edx, word[WIN_POS + edx * 2]
cmp edx, [current_slot_idx]
jne @f
inc eax
;--------------------------------------
align 4
@@:
mov edx, [current_slot_idx]
shl edx, 5
add edx, window_data
movzx ebx, [edx + WDATA.fl_wstyle]
and bl, 0x0F
cmp bl, 3
je .draw_caption_style_3
cmp bl, 4
je .draw_caption_style_3
jmp .not_style_3
;--------------------------------------
align 4
.draw_caption_style_3:
push edx
call drawwindow_IV_caption
add esp, 4
jmp .2
;--------------------------------------
align 4
.not_style_3:
cmp bl, 2
jne .not_style_2
call drawwindow_III_caption
jmp .2
;--------------------------------------
align 4
.not_style_2:
cmp bl, 0
jne .2
call drawwindow_I_caption
;--------------------------------------
align 4
.2:
mov edi, [current_slot_idx]
shl edi, BSF sizeof.WDATA
test [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
jz .exit
mov edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption]
or edx, edx
jz .exit
mov ebp, [edi + window_data + WDATA.box.left - 2]
mov bp, word[edi + window_data + WDATA.box.top]
movzx eax, [edi + window_data + WDATA.fl_wstyle]
and al, 0x0F
cmp al, 3
je .skinned
cmp al, 4
je .skinned
jmp .not_skinned
;--------------------------------------
align 4
.skinned:
movzx eax, word[edi + window_data + WDATA.box.width]
sub ax, [_skinmargins.left]
sub ax, [_skinmargins.right]
js .exit
mov ebx, dword[_skinmargins.left - 2]
mov bx, word[_skinh]
sub bx, [_skinmargins.bottom]
sub bx, [_skinmargins.top]
sar bx, 1
add bx, [_skinmargins.top]
sub bx, 8
jmp .dodraw
;--------------------------------------
align 4
.not_skinned:
cmp al, 1
je .exit
movzx eax, word[edi + window_data + WDATA.box.width]
sub eax, 16
js .exit
mov ebx, 80002h
.dodraw:
shr eax, 3
mov esi, eax
add ebx, ebp
mov ecx, [common_colours + 16]
mov al, [edi*8 + SLOT_BASE + APPDATA.captionEncoding]
test al, al
jnz @f
mov al, 1
cmp byte [edx], 4
jnc @f
mov al, [edx]
test al, al
jz .exit
inc edx
@@:
shl eax, 28
or ecx, eax
xor edi, edi
stc
call dtext._
.exit:
jmp __sys_draw_pointer
;------------------------------------------------------------------------------
align 4
; Draw negative box
; edi = pointer to BOX struct
window._.draw_negative_box:
push eax ebx esi
mov esi, 0x01000000
;--------------------------------------
align 4
.1:
mov eax, [edi + BOX.left - 2]
mov ax, word[edi + BOX.left]
add ax, word[edi + BOX.width]
mov ebx, [edi + BOX.top - 2]
mov bx, word[edi + BOX.top]
add bx, word[edi + BOX.height]
call draw_rectangle.forced
pop esi ebx eax
ret
;------------------------------------------------------------------------------
;align 4
;------------------------------------------------------------------------------
;window._.end_moving__box: ;//////////////////////////////////////////////////
;------------------------------------------------------------------------------
;? Draw positive box
;------------------------------------------------------------------------------
;> edi = pointer to BOX struct
;------------------------------------------------------------------------------
; push eax ebx esi
; xor esi, esi
; jmp window._.draw_negative_box.1
;------------------------------------------------------------------------------
align 4
; void __fastcall get_window_rect(struct RECT* rc);
; ecx = pointer to RECT
window._.get_rect:
mov eax, [current_slot_idx]
shl eax, BSF sizeof.WDATA
mov edx, [eax + window_data + WDATA.box.left]
mov [ecx+RECT.left], edx
add edx, [eax + window_data + WDATA.box.width]
mov [ecx+RECT.right], edx
mov edx, [eax +window_data + WDATA.box.top]
mov [ecx+RECT.top], edx
add edx, [eax + window_data + WDATA.box.height]
mov [ecx+RECT.bottom], edx
ret
;------------------------------------------------------------------------------
align 4
; redraw all windows one above the window
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
;! corrupted edi
window._.redraw_top_wnd:
push 0
jmp window._.set_top_wnd.go
;------------------------------------------------------------------------------
align 4
; call set_screen for all windows one above the window
;> eax = left
;> ebx = top
;> ecx = right
;> edx = bottom
;> esi = process number
;! corrupted edi
window._.set_top_wnd:
push 1
.go:
push esi
pushfd
cli
push ebp
mov ebp, [thread_count]
cmp ebp, 1
jbe .exit
shl esi, BSF sizeof.WDATA
cmp [esi + window_data + WDATA.z_modif], ZPOS_ALWAYS_TOP
je .exit
push eax ;for num layout
push edx ecx ebx eax
movsx eax, byte [esi + window_data + WDATA.z_modif]
inc eax
mov dword[esp+10h], eax
;--------------------------------------
align 4
.layout:
mov esi, 1 ; = num in window stack
mov ebp, [thread_count]
;--------------------------------------
align 4
.next_window:
movzx edi, word[WIN_POS + esi * 2]
shl edi, BSF sizeof.WDATA ;size of TASKDATA and WDATA = 32 bytes
cmp byte [SLOT_BASE + edi*8 + APPDATA.state], TSTATE_FREE
je .skip_window
add edi, window_data
test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
jnz .skip_window
mov eax, [esp+10h]
cmp [edi + WDATA.z_modif], al
jne .skip_window
mov eax, [edi + WDATA.box.left]
cmp eax, [esp + RECT.right]
jg .skip_window
mov ebx, [edi + WDATA.box.top]
cmp ebx, [esp + RECT.bottom]
jg .skip_window
mov ecx, [edi + WDATA.box.width]
add ecx, eax
cmp ecx, [esp + RECT.left]
jl .skip_window
mov edx, [edi + WDATA.box.height]
add edx, ebx
cmp edx, [esp + RECT.top]
jl .skip_window
cmp eax, [esp + RECT.left]
jae @f
mov eax, [esp + RECT.left]
;--------------------------------------
align 4
@@:
cmp ebx, [esp + RECT.top]
jae @f
mov ebx, [esp + RECT.top]
;--------------------------------------
align 4
@@:
cmp ecx, [esp + RECT.right]
jbe @f
mov ecx, [esp + RECT.right]
;--------------------------------------
align 4
@@:
cmp edx, [esp + RECT.bottom]
jbe @f
mov edx, [esp + RECT.bottom]
;--------------------------------------
align 4
@@:
cmp dword[esp+32], 0
je .set_fl_redraw
push esi
movzx esi, word[WIN_POS + esi * 2]
call window._.set_screen
pop esi
jmp @f
.set_fl_redraw:
mov [edi + WDATA.fl_redraw], 1 ;set redraw flag
@@:
;--------------------------------------
align 4
.skip_window:
inc esi
dec ebp
jnz .next_window
;--------------------------------------
inc dword[esp+10h]
cmp byte[esp+10h], ZPOS_ALWAYS_TOP
jle .layout
;-------------------------------------
pop eax ebx ecx edx
pop ebp ;del num layout
;-------------------------------------
align 4
.exit:
pop ebp
popfd
pop esi
add esp, 4 ;dword for 0/1 - set_screen/fl_redraw
ret