diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 70bfea382e..8165c52df6 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -597,13 +597,13 @@ term9: shl esi,5 add esi,window_data mov eax,[esi+WDATA.box.left] - mov [dlx],eax + mov [draw_limits.left],eax add eax,[esi+WDATA.box.width] - mov [dlxe],eax + mov [draw_limits.right],eax mov eax,[esi+WDATA.box.top] - mov [dly],eax + mov [draw_limits.top],eax add eax,[esi+WDATA.box.height] - mov [dlye],eax + mov [draw_limits.bottom],eax xor eax, eax mov [esi+WDATA.box.left],eax @@ -807,10 +807,10 @@ term9: ; call systest sti ; .. and life goes on - mov eax, [dlx] - mov ebx, [dly] - mov ecx, [dlxe] - mov edx, [dlye] + mov eax, [draw_limits.left] + mov ebx, [draw_limits.top] + mov ecx, [draw_limits.right] + mov edx, [draw_limits.bottom] call calculatescreen xor eax, eax xor esi, esi diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index a2fa191453..45844600d2 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -152,7 +152,7 @@ iglobal dd display_number ; 47-WriteNum dd 0 ; 48-SetRedrawType and SetButtonType dd 0 ; 49-Advanced Power Management (APM) - dd random_shaped_window ; 50-Window shape & scale + dd syscall_set_window_shape ; 50-Window shape & scale dd syscall_threads ; 51-Threads dd stack_driver_stat ; 52-Stack driver status dd socket ; 53-Socket interface @@ -229,7 +229,7 @@ iglobal dd reserve_free_irq ; 45-ReserveIrq and FreeIrq dd syscall_reserveportarea ; 46-ReservePortArea and FreePortArea dd cross_order ; 47-WriteNum - dd display_settings ; 48-SetRedrawType and SetButtonType + dd syscall_display_settings ; 48-SetRedrawType and SetButtonType dd sys_apm ; 49-Advanced Power Management (APM) dd cross_order ; 50-Window shape & scale dd cross_order ; 51-Threads diff --git a/kernel/trunk/gui/button.inc b/kernel/trunk/gui/button.inc index e042a3a02b..bda7acf276 100644 --- a/kernel/trunk/gui/button.inc +++ b/kernel/trunk/gui/button.inc @@ -42,22 +42,22 @@ align 4 ;------------------------------------------------------------------------------ syscall_button: ;///// system function 8 ////////////////////////////////////// ;------------------------------------------------------------------------------ -; Define/undefine GUI button object +;? Define/undefine GUI button object ;------------------------------------------------------------------------------ -; Define button arguments: -; ebx = pack[16(x), 16(width)] -; ecx = pack[16(y), 16(height)] -; edx = pack[8(flags), 24(button identifier)] -; flags bits: -; 7 (31) = 0 -; 6 (30) = don't draw button -; 5 (29) = don't draw button frame when pressed -; esi = button color +;; Define button: +;> ebx = pack[16(x), 16(width)] +;> ecx = pack[16(y), 16(height)] +;> edx = pack[8(flags), 24(button identifier)] +;> flags bits: +;> 7 (31) = 0 +;> 6 (30) = don't draw button +;> 5 (29) = don't draw button frame when pressed +;> esi = button color ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; Undefine button arguments: -; edx = pack[8(flags), 24(button identifier)] -; flags bits: -; 7 (31) = 1 +;; Undefine button: +;> edx = pack[8(flags), 24(button identifier)] +;> flags bits: +;> 7 (31) = 1 ;------------------------------------------------------------------------------ ; do we actually need to undefine the button? test edx, 0x80000000 @@ -264,7 +264,7 @@ align 4 ;------------------------------------------------------------------------------ check_buttons: ;/////////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ cmp byte[BTN_DOWN], 0 ; mouse buttons pressed jnz @f @@ -460,7 +460,7 @@ check_buttons: ;/////////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ button._.dececx: ;///////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ sub cl, 0x20 jnc @f @@ -478,7 +478,7 @@ button._.dececx: ;///////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ button._.incecx: ;///////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ add cl, 0x20 jnc @f @@ -496,7 +496,7 @@ button._.incecx: ;///////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ button._.incecx2: ;//////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ add cl, 0x14 jnc @f @@ -514,7 +514,7 @@ button._.incecx2: ;//////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ button._.button_dececx: ;////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ cmp [buttontype], 1 jne .finish @@ -545,76 +545,35 @@ button._.button_dececx: ;////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ button._.negative_button: ;//////////////////////////////////////////////////// ;------------------------------------------------------------------------------ -; +;? ;------------------------------------------------------------------------------ - ; If requested, do not display button border on press. + ; if requested, do not display button border on press. test ebx, 0x20000000 - jz .draw_negative_button - ret + jnz .exit - .draw_negative_button: pushad - mov ebx, dword[eax + SYS_BUTTON.left] - mov ecx, dword[eax + SYS_BUTTON.top] + xchg esi, eax + + movzx ecx, [esi + SYS_BUTTON.pslot] + shl ecx, 5 + add ecx, window_data + + mov eax, dword[esi + SYS_BUTTON.left] + mov ebx, dword[esi + SYS_BUTTON.top] + add eax, [ecx + WDATA.box.left] + add ebx, [ecx + WDATA.box.top] + push eax ebx + pop edx ecx + rol eax, 16 rol ebx, 16 - rol ecx, 16 - push ebx ecx + add ax, cx + add bx, dx - ; calculate window-relative coordinates - shr ebx, 16 - shr ecx, 16 - movzx eax, word[eax + SYS_BUTTON.pslot] - shl eax, 5 - add eax, window_data - add ebx, [eax + WDATA.box.left] - add ecx, [eax + WDATA.box.top] - - xor edi, edi - inc edi - - ; top border - mov eax, ebx - shl eax, 16 - mov ax, bx - add ax, [esp + 4] - mov ebx, ecx - shl ebx, 16 - mov bx, cx - push ebx - mov ecx, 0x01000000 - call [draw_line] - - ; bottom border - movzx edx, word[esp + 4 + 0] - add ebx, edx - shl edx, 16 - add ebx, edx - call [draw_line] - - ; left border - pop ebx - push edx - mov edx, eax - shr edx, 16 - mov ax, dx - mov edx, ebx - shr edx, 16 - mov bx, dx - add bx, [esp + 4 + 0] - pop edx - add ebx, 0x00010000 - dec bx - call [draw_line] - - ; right border - mov dx, [esp + 4] - add ax, dx - shl edx, 16 - add eax, edx - call [draw_line] - - pop ecx ebx + mov esi, 0x01000000 + call draw_rectangle.forced popad + + .exit: ret diff --git a/kernel/trunk/gui/skincode.inc b/kernel/trunk/gui/skincode.inc index 9e6ffbce96..7012f74b9e 100644 --- a/kernel/trunk/gui/skincode.inc +++ b/kernel/trunk/gui/skincode.inc @@ -68,10 +68,10 @@ ends struct SKIN_BUTTONS .type dd ? - .pos: + .pos: .left dw ? .top dw ? - .size: + .size: .width dw ? .height dw ? ends @@ -311,7 +311,6 @@ drawwindow_IV: ; shr esi,1 ; and esi,0x007f7f7f mov esi,[ebp+SKIN_DATA.colors.outer] - or [edi+WDATA.fl_wdrawn], 4 call draw_rectangle mov ecx,3 _dw3l: @@ -455,12 +454,6 @@ drawwindow_IV: no_skin_add_button: pop edi - and [edi+WDATA.fl_wdrawn], not 4 - test [edi+WDATA.fl_wdrawn], 2 - jz @f - call drawwindowframes2 -@@: - popa ret 4 diff --git a/kernel/trunk/gui/window.inc b/kernel/trunk/gui/window.inc index 58be79a6dc..6ec00d6afe 100644 --- a/kernel/trunk/gui/window.inc +++ b/kernel/trunk/gui/window.inc @@ -1,1815 +1,1824 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; ;; -;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; -;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; -;; Distributed under terms of the GNU General Public License ;; -;; ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -$Revision$ - - -get_titlebar_height: ; edi = window draw_data pointer - mov al,[edi+WDATA.fl_wstyle] - and al,0x0F - cmp al,0x03 - jne @f - mov eax,[_skinh] - ret - @@: mov eax,21 - ret - -get_rolledup_height: ; edi = window draw_data pointer - mov al,[edi+WDATA.fl_wstyle] - and al,0x0F - cmp al,0x03 - jb @f - mov eax,[_skinh] - add eax,3 - ret - @@: or al,al - jnz @f - mov eax,21 - ret - @@: mov eax,21+2 - ret - - -setwindowdefaults: - pushad - - xor eax,eax - mov ecx,WIN_STACK - @@: - inc eax - add ecx,2 - mov [ecx+0x000],ax ; process no - mov [ecx+0x400],ax ; positions in stack - cmp ecx,WIN_POS-2 ; the more high, the more surface - jnz @b - - popad - ret - - - -; eax = cx -; ebx = cy -; ecx = ex -; edx = ey -; идея: перебрать все окна, начиная с самого нижнего, -; и для попавших в заданную область -; частей окон вызвать setscreen -align 4 -calculatescreen: - pushad - pushfd - cli - - push edx ecx ebx eax - - mov esi, 1 - call setscreen - - mov ebp, [TASK_COUNT] ; number of processes - cmp ebp, 1 - jbe .finish - align 4 - .new_wnd: - movzx edi, word [WIN_POS + esi * 2] - shl edi, 5 - - cmp [CURRENT_TASK+edi+TASKDATA.state], byte 9 - je .not_wnd - - add edi, window_data - test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .not_wnd - - mov eax,[edi+WDATA.box.left] - cmp eax, [esp+RECT.right] - ja .out_of_bounds - mov ebx,[edi+WDATA.box.top] - cmp ebx, [esp+RECT.bottom] - ja .out_of_bounds - mov ecx,[edi+WDATA.box.width] - add ecx, eax - cmp ecx, [esp+RECT.left] - jb .out_of_bounds - mov edx,[edi+WDATA.box.height] - add edx, ebx - cmp edx, [esp+RECT.top] - jb .out_of_bounds - - cmp eax, [esp+RECT.left] - jae @f - mov eax, [esp+RECT.left] - @@: - cmp ebx, [esp+RECT.top] - jae @f - mov ebx, [esp+RECT.top] - @@: - cmp ecx, [esp+RECT.right] - jbe @f - mov ecx, [esp+RECT.right] - @@: - cmp edx, [esp+RECT.bottom] - jbe @f - mov edx, [esp+RECT.bottom] - @@: - - push esi - movzx esi, word [WIN_POS + esi * 2] - call setscreen - pop esi - - .not_wnd: - .out_of_bounds: - inc esi - dec ebp - jnz .new_wnd - .finish: - - pop eax ebx ecx edx - - popfd - popad -ret - - - -virtual at esp - ff_x dd ? - ff_y dd ? - ff_width dd ? - ff_xsz dd ? - ff_ysz dd ? - ff_scale dd ? -end virtual - -align 4 -; резервирует место под окно заданного процесса -setscreen: -; eax x start -; ebx y start -; ecx x end -; edx y end -; esi process number -pushad -; \begin{diamond}[29.08.2006] - cmp esi, 1 - jz @f - mov edi, esi - shl edi, 5 - cmp [edi+window_data+WDATA.box.width], 0 - jnz @f - cmp [edi+window_data+WDATA.box.height], 0 - jz .ret -@@: -; \end{diamond}[29.08.2006] - mov edi, esi ;;;word [esi*2+WIN_POS] - shl edi, 8 - add edi, SLOT_BASE ; address of random shaped window area - cmp [edi+APPDATA.wnd_shape], dword 0 - jne .free_form - - ; get x&y size - sub ecx, eax - sub edx, ebx - inc ecx - inc edx - - ; get WinMap start - mov edi, [Screen_Max_X] ; screen_sx - inc edi - imul edi, ebx - add edi, eax - add edi, [_WinMapAddress] - - .new_y: - push ecx ; sx - push edx - - mov edx, esi - align 4 - .new_x: - mov byte [edi], dl - inc edi - dec ecx - jnz .new_x - - pop edx - pop ecx - add edi, [Screen_Max_X] - inc edi - sub edi, ecx - dec edx - jnz .new_y -.ret: - popad - ret - .read_byte: - ;eax - address - ;esi - slot - push eax - push ecx - push edx - push esi - -; mov edx,eax -; mov eax,esi - xchg eax,esi - lea ecx,[esp+12] - mov edx,1 - call read_process_memory - pop esi - pop edx - pop ecx - pop eax - ret - .free_form: - - ; 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 dword [edi+APPDATA.wnd_shape_scale] ; push scale first -> for loop - - ; get WinMap start -> ebp - push eax - mov eax, [Screen_Max_X] ; screen_sx - inc eax - imul eax, ebx - add eax, [esp] - add eax, [_WinMapAddress] - 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, 5 - 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] - - .ff_new_y: - mov edx, [ff_x] - - .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 -- - inc ebp - inc edx - cmp edx, [ff_xsz] - jb .ff_new_x - sub ebp, [ff_xsz] - add ebp, [ff_x] - add ebp, [Screen_Max_X] ; screen.x - inc ebp - inc ebx - cmp ebx, [ff_ysz] - jb .ff_new_y - - add esp, 24 -popad -ret - - -iglobal -align 4 -f48call: - dd display_settings.00 - dd display_settings.01 - dd display_settings.02 - dd display_settings.03 - dd display_settings.04 - dd display_settings.05 - dd display_settings.06 - dd display_settings.07 - dd display_settings.08 -endg - -display_settings: - -; ebx = 0 ; DISPLAY redraw -; ebx = 0 ; all -; -; ebx = 1 ; BUTTON type -; ebx = 0 ; flat -; ebx = 1 ; 3D -; ebx = 2 ; set WINDOW colours -; ebx = pointer to table -; ecx = number of bytes define -; ebx = 3 ; get WINDOW colours -; ebx = pointer to table -; ecx = number of bytes wanted -; ebx = 4 ; get skin height -; input : nothing -; output : eax = skin height in pixel -; ebx = 5 ; get screen workarea -; input : nothing -; output : eax = [left]*65536+[right] -; ebx = [top]*65536+[bottom] -; ebx = 6 ; set screen workarea -; input : ecx = [left]*65536+[right] -; edx = [top]*65536+[bottom] -; output : nothing -; ebx = 7 ; get skin margins -; input : nothing -; output : eax = [left]*65536+[right] -; ebx = [top]*65536+[bottom] -; ebx = 8 ; set window skin -; input : ecx = pointer to file info block -; output : eax = FS error code - cmp ebx,8 - ja .fail - jmp dword [f48call+ebx*4] -.00: - -; redraw display - xor eax,eax - inc ebx - cmp [windowtypechanged],dword ebx ;ebx=1 - jne .fail - mov [windowtypechanged],dword eax ;eax=0 - .redraw_screen_direct: - xor eax,eax - mov [dlx],dword eax - mov [dly],dword eax - mov eax,[Screen_Max_X] - mov [dlxe],eax - mov eax,[Screen_Max_Y] - mov [dlye],eax - mov eax,window_data - jmp redrawscreen -.fail: - ret -.01: -; button type - and ecx,1 - cmp ecx,[buttontype] - je .01_ex - mov [buttontype],ecx - mov [windowtypechanged],dword ebx ;eax=1 -.01_ex: - ret - -.02: -; set common window colours - dec ebx - mov [windowtypechanged],dword ebx ;eax=1 - mov esi,ecx - and edx,127 - mov edi,common_colours - mov ecx,edx -; cld not need because cld is set previous call - rep movsb - ret - -.03: -; get common window colours - mov edi,ecx - and edx,127 - mov esi,common_colours - mov ecx,edx -; cld not need because cld is set previous call - rep movsb - ret - -.04: -; get skin height - mov eax,[_skinh] - mov [esp+32],eax - ret - -.05: -; get screen workarea - mov eax,[screen_workarea.left-2] - mov ax,word[screen_workarea.right] - mov [esp+32],eax - mov eax,[screen_workarea.top-2] - mov ax,word[screen_workarea.bottom] - mov [esp+20],eax - ret - -.06: -; set screen workarea - mov edi,dword[Screen_Max_X] - movsx eax,word[esp+28+2] ;ecx in the stack - movsx ebx,word[esp+28] - cmp eax,ebx - jge .lp1 - or eax,eax;[Screen_Max_X] - jl @f - mov [screen_workarea.left],eax - @@: cmp ebx,edi ;[Screen_Max_X] - jg .lp1 - mov [screen_workarea.right],ebx - .lp1: movsx eax,word[esp+24+2] ;edx in the stack - movsx ebx,word[esp+24] - cmp eax,ebx - jge .lp2 - or eax,eax;[0xFE04] - jl @f - mov [screen_workarea.top],eax - @@: cmp ebx,edi ;[Screen_Max_Y] - jg .lp2 - mov [screen_workarea.bottom],ebx - .lp2: call repos_windows - xor eax, eax - xor ebx, ebx - mov ecx, [Screen_Max_X] - mov edx, [Screen_Max_Y] - jmp calculatescreen - -.07: -; get skin margins - mov eax,dword[_skinmargins+0] - mov [esp+32],eax - mov eax,dword[_skinmargins+4] - mov [esp+20],eax - ret - -.08: -; set window skin - mov ebx, ecx - call read_skin_file - - mov [esp+32], eax - test eax, eax - jnz .ret - xor eax, eax - xor ebx, ebx - mov ecx, [Screen_Max_X] - mov edx, [Screen_Max_Y] - call calculatescreen - jmp .redraw_screen_direct -.ret: - ret - - -repos_windows: - mov ecx,[TASK_COUNT] - mov edi, window_data+0x20*2 - call force_redraw_background - dec ecx - jge @f - ret - @@: mov [edi+WDATA.fl_redraw],1 - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jz .lp2 - 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 .lp1 - sub eax,[screen_workarea.bottom] - neg eax - mov [edi+WDATA.box.height],eax - .lp1: - - call set_window_clientbox - add edi,0x20 - loop @b - ret - .lp2: mov eax,[edi+WDATA.box.left] - add eax,[edi+WDATA.box.width] - mov ebx,[Screen_Max_X] -; inc ebx - cmp eax,ebx - jle .lp4 - mov eax,[edi+WDATA.box.width] - sub eax,ebx - jle .lp3 - mov [edi+WDATA.box.width],ebx - .lp3: sub ebx,[edi+WDATA.box.width] - mov [edi+WDATA.box.left],ebx - .lp4: mov eax,[edi+WDATA.box.top] - add eax,[edi+WDATA.box.height] - mov ebx,[Screen_Max_Y] -; inc ebx - cmp eax,ebx - jle .lp6 - mov eax,[edi+WDATA.box.height] - sub eax,ebx - jle .lp5 - mov [edi+WDATA.box.height],ebx - .lp5: sub ebx,[edi+WDATA.box.height] - mov [edi+WDATA.box.top],ebx - .lp6: jmp .lp1 - -uglobal - common_colours: - times 128 db 0x0 -endg - - - - -check_window_position: - - pushad ; window inside screen ? - - mov eax, [edi+WDATA.box.left] - mov ebx, [edi+WDATA.box.top] - mov ecx, [edi+WDATA.box.width] - mov edx, [edi+WDATA.box.height] - - cmp ecx,[Screen_Max_X] ; check x size - jbe x_size_ok - mov ecx,[Screen_Max_X] - mov [edi+WDATA.box.width],ecx - - x_size_ok: - - cmp edx,[Screen_Max_Y] ; check y size - jbe y_size_ok - mov edx,[Screen_Max_Y] - mov [edi+WDATA.box.height],edx - - y_size_ok: - - cmp eax,0 ; check x pos - jnle @f - xor eax,eax - mov [edi+WDATA.box.left],eax - jmp x_pos_ok - @@: - add eax,ecx - cmp eax,[Screen_Max_X] - jbe x_pos_ok - mov eax,[Screen_Max_X] - sub eax,ecx - mov [edi+WDATA.box.left],eax - - x_pos_ok: - - cmp ebx,0 ; check x pos - jnle @f - xor ebx,ebx - mov [edi+WDATA.box.top],ebx - jmp y_pos_ok - @@: - add ebx,edx - cmp ebx,[Screen_Max_Y] - jbe y_pos_ok - mov ebx,[Screen_Max_Y] - sub ebx,edx - mov [edi+WDATA.box.top],ebx - - y_pos_ok: - - popad - - ret - - -uglobal - new_window_starting dd 0 -endg - - -sys_window_mouse: - - push eax - - mov eax,[timer_ticks] - cmp [new_window_starting],eax - jb swml1 - - mov [MOUSE_BACKGROUND],byte 0 ; no mouse background - mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse - - mov [new_window_starting],eax - - swml1: - - pop eax - - ret - - - - -drawwindow_I_caption: - - mov ecx,[edx+WDATA.cl_titlebar] ; grab bar - push ecx - mov esi,edx - mov edx,[esi+WDATA.box.top] - add edx,1 - mov ebx,[esi+WDATA.box.top] - add ebx,21 - mov eax,[esi+WDATA.box.top] - add eax,[esi+WDATA.box.height] - cmp ebx,eax - jb .wdsizeok - mov ebx,eax - .wdsizeok: - push ebx - .drwi: - 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] - sub eax,1 - push edx - mov edx,0x80000000 - mov ecx,[esi+WDATA.cl_titlebar] - and ecx,edx - cmp ecx,edx - jnz .nofa - mov ecx,[esi+WDATA.cl_titlebar] - sub ecx,0x00040404 - mov [esi+WDATA.cl_titlebar],ecx - and ecx,0x00ffffff - jmp .faj - .nofa: - mov ecx,[esi+WDATA.cl_titlebar] - and ecx,0x00ffffff - .faj: - pop edx - mov edi,0 - call [draw_line] - inc edx - cmp edx,[esp] - jb .drwi - add esp,4 - pop ecx - mov [esi+WDATA.cl_titlebar],ecx - - ret - - -drawwindow_I: - - pushad - or [edx+WDATA.fl_wdrawn], 4 - - mov esi,[edx+WDATA.cl_frames] ; rectangle - mov eax,[edx+WDATA.box.left] - shl eax,16 - add eax,[edx+WDATA.box.left] - add eax,[edx+WDATA.box.width] - mov ebx,[edx+WDATA.box.top] - shl ebx,16 - add ebx,[edx+WDATA.box.top] - add ebx,[edx+WDATA.box.height] - call draw_rectangle - - and [edx+WDATA.fl_wdrawn], not 4 - test [edx+WDATA.fl_wdrawn], 2 - jz @f - call drawwindowframes2 -@@: - - call drawwindow_I_caption - - mov edx,[esi+WDATA.box.top] ; inside work area - add edx,21+5 - mov ebx,[esi+WDATA.box.top] - add ebx,[esi+WDATA.box.height] - cmp edx,ebx - jg noinside - mov eax,1 - mov ebx,21 - mov ecx,[esi+WDATA.box.width] - mov edx,[esi+WDATA.box.height] - mov edi,[esi+WDATA.cl_workarea] - test edi,0x40000000 - jnz noinside - call [drawbar] - noinside: - - popad - - ret - - -draw_rectangle: - -r_eax equ [esp+28] ; x start -r_ax equ [esp+30] ; x end -r_ebx equ [esp+16] ; y start -r_bx equ [esp+18] ; y end -;esi ; color - - pushad - - mov ecx,esi ; yb,xb -> yb,xe - mov eax, r_eax - rol eax, 16 - mov ebx,r_ebx - shl ebx,16 - mov bx,r_ebx - xor edi, edi - call [draw_line] - - mov ebx,r_bx ; ye,xb -> ye,xe - shl ebx,16 - mov bx,r_bx - call [draw_line] - - mov ecx,esi ; ya,xa -> ye,xa - mov eax,r_eax - shl eax,16 - mov ax,r_eax - mov ebx,r_ebx - shl ebx,16 - mov bx,r_bx - mov edi,0 - call [draw_line] - - mov eax,r_ax ; ya,xe -> ye,xe - shl eax,16 - mov ax,r_ax - call [draw_line] - - popad - ret - - -drawwindow_III_caption: - - mov ecx,[edx+WDATA.cl_titlebar] ; GRAB BAR - 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 .wdsizeok - mov ebx,eax - .wdsizeok: - push ebx - .drwi: - 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 .nofa - add ecx,0x040404 - .nofa: - test ecx,0x80000000 - jz .nofa2 - sub ecx,0x040404 - .nofa2: - mov [esi+WDATA.cl_titlebar],ecx - and ecx,0xffffff - xor edi, edi - call [draw_line] - inc edx - cmp edx,[esp] - jb .drwi - add esp,4 - pop ecx - mov [esi+WDATA.cl_titlebar],ecx - - ret - - -drawwindow_III: - - pushad - - mov edi,edx ; RECTANGLE - mov eax,[edi+WDATA.box.left] - shl eax,16 - mov ax, word [edi+WDATA.box.left] - add ax, word [edi+WDATA.box.width] - mov ebx,[edi+WDATA.box.top] - shl ebx,16 - mov bx, word [edi+WDATA.box.top] - add bx, word [edi+WDATA.box.height] - mov esi,[edi+WDATA.cl_frames] - shr esi,1 - and esi,0x007f7f7f - push esi - or [edi+WDATA.fl_wdrawn], 4 - call draw_rectangle - and [edi+WDATA.fl_wdrawn], not 4 - test [edi+WDATA.fl_wdrawn], 2 - jz @f - call drawwindowframes2 -@@: - mov ecx,3 - dw3l: - add eax,1*65536-1 - add ebx,1*65536-1 - mov esi,[edi+WDATA.cl_frames] - call draw_rectangle - dec ecx - jnz dw3l - pop esi - add eax,1*65536-1 - add ebx,1*65536-1 - call draw_rectangle - - call drawwindow_III_caption - - mov edx,[esi+WDATA.box.top] ; WORK AREA - add edx,21+5 - mov ebx,[esi+WDATA.box.top] - add ebx,[esi+WDATA.box.height] - cmp edx,ebx - jg noinside2 - mov eax,5 - mov ebx,20 - mov ecx,[esi+WDATA.box.width] - mov edx,[esi+WDATA.box.height] - sub ecx,4 - sub edx,4 - mov edi,[esi+WDATA.cl_workarea] - test edi,0x40000000 - jnz noinside2 - call [drawbar] - noinside2: - - popad - - ret - - - -; activate window -align 4 -windowactivate: - - ; esi = abs mem position in stack 0xC400+ - - pushad - - ; if type of current active window is 3, - ; it must be redrawn - mov eax, [TASK_COUNT] - movzx eax, word [WIN_POS + eax*2] - shl eax, 5 - add eax, window_data - mov ebx, [eax + WDATA.cl_workarea] - and ebx, 0x0f000000 - cmp ebx, 0x03000000 - je .set_WDATA_fl_redraw ; for 3 and 4 style - cmp ebx, 0x04000000 - je .set_WDATA_fl_redraw - jmp @f - .set_WDATA_fl_redraw: - mov [eax + WDATA.fl_redraw], byte 1 - @@: - - push esi - movzx eax, word [esi] ; ax <- process no - movzx eax, word [WIN_STACK+eax*2] ; ax <- position in window stack - - xor esi, esi ; drop others - waloop: - cmp esi, dword [TASK_COUNT] - jae wacont - inc esi - lea edi, [WIN_STACK + esi*2] - mov bx, [edi] ; position of the current process - cmp bx, ax - jbe @f - dec bx ; upper? => drop! - mov [edi], bx - @@: - jmp waloop - wacont: - ; set to no 1 - pop esi ; esi = pointer at 0xC400 - - movzx eax, word [esi] - mov bx, [TASK_COUNT] ; number of processes - mov [WIN_STACK+eax*2], bx ; this is the last (and the upper) - - ; update on screen -window stack - xor esi, esi - waloop2: - mov edi, [TASK_COUNT] - cmp esi, edi - jae wacont2 - inc esi - movzx ebx, word [esi*2 + WIN_STACK] - mov [ebx*2 + WIN_POS], si - jmp waloop2 - wacont2: - mov [KEY_COUNT], byte 0 ; empty keyboard buffer - mov [BTN_COUNT], byte 0 ; empty button buffer - mov [MOUSE_SCROLL_H], word 0 ; zero mouse z-index - mov [MOUSE_SCROLL_V], word 0 ; zero mouse z-index - popad - ret - - -; check if window is necessary to draw - -checkwindowdraw: - - ; edi = position in window_data+ - - mov eax, [edi + WDATA.cl_workarea] - and eax, 0x0f000000 - cmp eax, 0x03000000 - je .return_yes ; window type 3 - cmp eax, 0x04000000 - je .return_yes ; window type 4 - - mov esi, edi - sub esi, window_data - shr esi, 5 - - ; esi = process number - - movzx eax, word [WIN_STACK + esi * 2] ; get value of the curr process - lea esi, [WIN_POS + eax * 2] ; get address of this process at 0xC400 - - push esi - - .new_check: - - pop esi - add esi, 2 - push esi - - mov eax, [TASK_COUNT] - lea eax, word [WIN_POS + eax * 2] ; number of the upper window - - cmp esi, eax - ja .all_wnds_to_top - - movzx eax, word [esi] - shl eax, 5 - cmp [CURRENT_TASK + eax + TASKDATA.state], byte 9 - je .new_check ; skip dead windows - - lea esi, [eax+window_data] - - mov ebx, [edi+WDATA.box.top] ; y0 - mov edx, [edi+WDATA.box.height] - add edx, ebx ; y0e - - mov ecx, [esi+WDATA.box.top] ; y ; y check - cmp ecx, edx - jae .new_check ; y < y0e - mov eax, [esi+WDATA.box.height] - add ecx, eax ; ye - cmp ebx, ecx ; y0 >= ye - ja .new_check - - mov eax, [edi+WDATA.box.left] ; x0 - mov ecx, [edi+WDATA.box.width] - add ecx, eax ; x0e - - mov edx, [esi+WDATA.box.left] ; x ; x check - cmp edx, ecx - jae .new_check ; x < x0e - mov ecx, [esi+WDATA.box.width] - add edx, ecx - cmp eax, edx - ja .new_check - - pop esi - .return_yes: - mov ecx,1 ; overlap some window - ret - - .all_wnds_to_top: - - pop esi - - xor ecx, ecx ; passed all windows to top - ret - - - - -waredraw: ; if redraw necessary at activate - - pushad - - call checkwindowdraw ; draw window on activation ? - test ecx, ecx - jz .do_not_draw - - popad - mov [MOUSE_DOWN], byte 1 ; do draw mouse - call windowactivate - - ; update screen info - pushad - mov edi, [TASK_COUNT] ; the last process (number) - movzx esi, word [WIN_POS + edi * 2] - shl esi, 5 - add esi, window_data - - ; coordinates of the upper window - mov eax, [esi + WDATA.box.left] ; cx - mov ebx, [esi + WDATA.box.top] ; cy - mov ecx, [esi + WDATA.box.width] ; sx - mov edx, [esi + WDATA.box.height] ; sy - - add ecx, eax ; ecx = x_end - add edx, ebx ; edx = y_end - - mov edi, [TASK_COUNT] - movzx esi, word [WIN_POS + edi * 2] - call setscreen - popad - - mov [edi + WDATA.fl_redraw], 1 ; redraw flag for app - mov [MOUSE_DOWN],byte 0 ; mouse down checks - - ret - - .do_not_draw: - - popad - - call windowactivate - mov [MOUSE_DOWN],byte 0 ; mouse down checks - mov [MOUSE_BACKGROUND],byte 0 ; no mouse background - mov [DONT_DRAW_MOUSE],byte 0 ; draw mouse - ret - - -; eax = window number on screen -; corrupts registers and [dl*] -minimize_window: - movzx eax, word [WIN_POS+eax*2] - shl eax, 5 - add eax, window_data - test [eax+WDATA.fl_wstate], WSTATE_MINIMIZED - jnz .skip_redrawings - pushfd - cli - or [eax+WDATA.fl_wstate], WSTATE_MINIMIZED - mov edi, eax - ;call calculatescreen - mov eax, [edi+WDATA.box.left] - mov [dlx], eax - mov ecx, eax - add ecx, [edi+WDATA.box.width] - mov [dlxe], ecx - mov ebx, [edi+WDATA.box.top] - mov [dly], ebx - mov edx, ebx - add edx, [edi+WDATA.box.height] - mov [dlye], edx - call calculatescreen - xor esi, esi - xor eax, eax - call redrawscreen - popfd -.skip_redrawings: - ret - -; eax = window number on screen -; corrupts registers and [dl*] -restore_minimized_window: - pushfd - cli - movzx esi, word [WIN_POS+eax*2] - mov edi, esi - shl edi, 5 - add edi, window_data - test [edi+WDATA.fl_wstate], WSTATE_MINIMIZED - jz .skip_redrawings - mov [edi+WDATA.fl_redraw], 1 - and [edi+WDATA.fl_wstate], not WSTATE_MINIMIZED - cmp eax, [TASK_COUNT] ; the uppermost window - jnz .no_uppermost - mov eax, [edi+WDATA.box.left] - mov ebx, [edi+WDATA.box.top] - mov ecx, eax - mov edx, ebx - add ecx, [edi+WDATA.box.width] - add edx, [edi+WDATA.box.height] - call setscreen - jmp .done -.no_uppermost: - mov eax, [edi+WDATA.box.left] - mov ebx, [edi+WDATA.box.top] - mov ecx, eax - mov edx, ebx - add ecx, [edi+WDATA.box.width] - add edx, [edi+WDATA.box.height] - call calculatescreen -.done: - mov [MOUSE_BACKGROUND],byte 0 ; no mouse under -.skip_redrawings: - popfd - ret - - -;iglobal -; window_moving db 'K : Window - move/resize',13,10,0 -; window_moved db 'K : Window - done',13,10,0 -;endg - -; check window touch -align 4 -checkwindows: - pushad - - cmp [window_minimize], 0 - je .no_minimizing - mov eax, [TASK_COUNT] ; the uppermost window - mov bl, 0 - xchg [window_minimize], bl - cmp bl, 1 - jne .restore - call minimize_window - jmp .continue - .restore: - call restore_minimized_window - .continue: - .no_minimizing: - - cmp [BTN_DOWN],byte 0 ; mouse buttons pressed ? - jne .mouse_buttons_pressed -;..................................... start 1/4 : modified by vhanla ................. - mov [bPressedMouseXY_W],0 -;..................................... end 1/4 : modified by vhanla ................... - popad - ret - .mouse_buttons_pressed: -;..................................... start 2/4 : modified by vhanla ................. -uglobal - bPressedMouseXY_W db 0x0 -endg -;..................................... end 2/4 : modified by vhanla ................... - mov esi,[TASK_COUNT] - inc esi - -;..................................... start 3/4 : modified by vhanla ................. - cmp [bPressedMouseXY_W],1 - ja @f - inc [bPressedMouseXY_W] - jnc @f - ;mov ax,[MOUSE_X] - ;mov [mx],ax - ;mov ax,[MOUSE_Y] - ;mov [my],ax - mov eax,dword[MOUSE_X] - mov dword[mx],eax - @@: -;..................................... end 3/4 : modified by vhanla ................... - - cwloop: - cmp esi,2 - jb .exit - - dec esi - movzx edi, word [WIN_POS + esi * 2] ; ebx - shl edi, 5 - add edi, window_data -; mov edi, ebx - mov ecx, [edi + WDATA.box.left] - mov edx, [edi + WDATA.box.top] - - mov eax,ecx - mov ebx,edx - test [edi+WDATA.fl_wstate],WSTATE_MINIMIZED - jnz cwloop - -;..................................... start 4/4 : modified by vhanla ................. - movzx eax, word [mx]; movzx eax,word[MOUSE_X] - movzx ebx, word [my]; movzx ebx,word[MOUSE_Y] -;..................................... endt 4/4 : modified by vhanla .................. - cmp ecx, eax - jae cwloop - cmp edx, ebx - jae cwloop - add ecx, [edi + WDATA.box.width] - add edx, [edi + WDATA.box.height] - cmp eax, ecx - jae cwloop - cmp ebx, edx - jae cwloop - - pushad - mov eax, esi - mov ebx, [TASK_COUNT] - cmp eax, ebx ; is this window active? - jz .move_resize_window - - cmp [bPressedMouseXY_W], 1 - ja .exit_popa - - ; eax = position in windowing stack - ; redraw must ? - lea esi, [WIN_POS + esi * 2] - call waredraw - .exit_popa: - add esp, 32 - - .exit: - popad - ret - - .move_resize_window: ; MOVE OR RESIZE WINDOW - popad - - ; Check for user enabled fixed window - mov edx, [edi + WDATA.cl_titlebar] - and edx, 0x0f000000 - cmp edx, 0x01000000 - jne .window_move_enabled_for_user - popad - ret - .window_move_enabled_for_user: - - test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP - jnz .no_resize_2 - - mov [do_resize_from_corner],byte 0 ; resize for skinned window - mov edx, [edi + WDATA.cl_workarea] - and edx, 0x0f000000 - cmp edx, 0x00000000 ;{test for resized} - je .no_resize_2 - cmp edx, 0x01000000 ;{test for resized} - je .no_resize_2 - cmp edx, 0x04000000 ;{test for resized} - je .no_resize_2 -; jb .no_resize_2 ; not type 2 wnd - - mov edx, [edi + WDATA.box.top] - add edx, [edi + WDATA.box.height] - sub edx, 6 ; edx = y_end - 6 - cmp ebx, edx ; ebx = mouse_y - jb .no_resize_2 - mov [do_resize_from_corner],byte 1 - jmp .continue - .no_resize_2: - - push eax - call get_titlebar_height - add eax,[edi + WDATA.box.top] - cmp ebx,eax - pop eax - jae .exit - - .continue: - -; push esi -; mov esi, window_moving -; call sys_msg_board_str -; pop esi - - mov ecx, [timer_ticks] ; double-click ? - mov edx, ecx - sub edx, [latest_window_touch] - mov [latest_window_touch], ecx - mov [latest_window_touch_delta], edx - - mov cl, [BTN_DOWN] ; save for shade check - mov [do_resize], cl - no_emulation_righ_button: - mov ecx, [edi + WDATA.box.left] - mov edx, [edi + WDATA.box.top] - - push eax ecx edx - mov [dlx], ecx ; save for drawlimits - mov [dly], edx - mov eax, [edi + WDATA.box.width] - add ecx, eax - mov eax, [edi + WDATA.box.height] - add edx, eax - mov [dlxe], ecx - mov [dlye], edx - pop edx ecx eax - - sub eax, ecx - sub ebx, edx - - mov esi, [MOUSE_X] - mov [WIN_TEMP_XY], esi - - pushad ; wait for putimages to finish -; mov ebx,5 -; call delay_hs - mov eax,[edi + WDATA.box.left] - mov [npx],eax - mov eax,[edi + WDATA.box.top] - mov [npy],eax - popad - - push eax ; save old coordinates - mov ax, word [edi + WDATA.box.left] - mov word [oldc+BOX.left],ax - mov ax, word [edi + WDATA.box.top] - mov word [oldc+BOX.top],ax - mov ax, word [edi + WDATA.box.width] - mov word [oldc+BOX.width],ax - mov word [npxe],ax - mov ax, word [edi + WDATA.box.height] - mov word [oldc+BOX.height],ax - mov word [npye],ax - pop eax - - call drawwindowframes - - mov [reposition],0 - mov [MOUSE_DOWN],byte 1 ; no reaction to mouse up/down - - ; move window - - newchm: - - mov [DONT_DRAW_MOUSE],byte 1 - - call checkidle - - call checkVga_N13 - - mov [MOUSE_BACKGROUND],byte 0 - - call [draw_pointer] - - pushad - call stack_handler - popad - - mov esi,[WIN_TEMP_XY] - cmp esi,[MOUSE_X] - je cwb - - mov cx,[MOUSE_X] - mov dx,[MOUSE_Y] - sub cx,ax - sub dx,bx - - push ax - push bx - - call drawwindowframes - - mov ax,[Screen_Max_X] - mov bx,[Screen_Max_Y] - - cmp [do_resize_from_corner],1 - je no_new_position - - mov word [npx],word 0 ; x repos ? - cmp ax,cx - jb noreposx - mov [reposition],1 - sub ax,word [npxe] - mov word [npx],ax - cmp ax,cx - jb noreposx - mov word [npx],cx - noreposx: - - mov word [npy],word 0 ; y repos ? - cmp bx,dx - jb noreposy - mov [reposition],1 - sub bx,word [npye] - mov word [npy],bx - cmp bx,dx - jb noreposy - mov word [npy],dx - noreposy: - - no_new_position: - - cmp [do_resize_from_corner],0 ; resize from right corner - je norepos_size - pushad - - mov edx,edi - sub edx,window_data - ;shr edx,5 - ;shl edx,8 - ;add edx,0x80000 ; process base at 0x80000+ - lea edx, [SLOT_BASE + edx*8] - - movzx eax,word [MOUSE_X] - cmp eax,[edi + WDATA.box.left] - jb nnepx - sub eax,[edi + WDATA.box.left] - cmp eax,32 ; [edx+0x90+8] - jge nnepx2 - mov eax,32 ; [edx+0x90+8] - nnepx2: - mov [npxe],eax - nnepx: - - call get_rolledup_height - mov ebx,eax - movzx eax,word [MOUSE_Y] - cmp eax,[edi + WDATA.box.top] - jb nnepy - sub eax,[edi + WDATA.box.top] - cmp eax,ebx ; [edx+0x90+12] - jge nnepy2 - mov eax,ebx ; [edx+0x90+12] - nnepy2: - mov [npye],eax - nnepy: - - mov [reposition],1 - - popad - norepos_size: - - pop bx - pop ax - call drawwindowframes - - mov esi,[MOUSE_X] - mov [WIN_TEMP_XY],esi - - cwb: - cmp [BTN_DOWN],byte 0 - jne newchm - ; new position done - mov [DONT_DRAW_MOUSE],byte 1 - mov cl,0 - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jnz @f - mov cl,[reposition] - call drawwindowframes - - mov eax,[npx] - mov [edi + WDATA.box.left],eax - mov eax,[npy] - mov [edi + WDATA.box.top],eax - mov eax,[npxe] - mov [edi + WDATA.box.width],eax - mov eax,[npye] - mov [edi + WDATA.box.height],eax - call set_window_clientbox - - @@: mov [reposition],cl - - cmp [reposition],1 ; save new position and size - jne no_bounds_save - push esi edi ecx - mov esi,edi - mov ecx,2 - test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP or WSTATE_MAXIMIZED - jnz @f - add ecx,2 - @@: sub edi,window_data - shr edi,5 - shl edi,8 - add edi,SLOT_BASE+APPDATA.saved_box - cld - rep movsd - pop ecx edi esi - no_bounds_save: - - pushad ; WINDOW SHADE/FULLSCREEN - - ;{doule click not worked for 4 type window} - mov edx, [edi + WDATA.cl_workarea] - and edx, 0x0f000000 - cmp edx, 0x00000000 - je no_fullscreen_restore - cmp edx, 0x01000000 - je no_fullscreen_restore - - cmp [reposition],1 - je no_window_sizing - mov edx,edi - sub edx,window_data - shr edx,5 - shl edx,8 - add edx,SLOT_BASE ; process base at 0x80000+ - - cmp [do_resize],2 ; window shade ? - jne no_window_shade - mov [reposition],1 - - test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP - jnz wnd_rolldown - wnd_rollup: - or [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP - call get_rolledup_height - jmp @f - wnd_rolldown: - and [edi+WDATA.fl_wstate],not WSTATE_ROLLEDUP - mov eax,[edx + APPDATA.saved_box.height] ; 0x90+BOX.height - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jz @f - mov eax,[screen_workarea.bottom] - sub eax,[screen_workarea.top] - @@: mov [edi+WDATA.box.height],eax - add eax, [edi+WDATA.box.top] - cmp eax, [Screen_Max_Y] - jbe @f - mov eax, [Screen_Max_Y] - sub eax, [edi+WDATA.box.height] - mov [edi+WDATA.box.top], eax - @@: call check_window_position - call set_window_clientbox - - no_window_shade: - - push edx - mov edx, [edi + WDATA.cl_workarea] - and edx, 0x0f000000 - cmp edx, 0x04000000 - pop edx - je no_fullscreen_restore - - cmp [do_resize],1 ; fullscreen/restore ? - jne no_fullscreen_restore - cmp [latest_window_touch_delta],dword 50 - jg no_fullscreen_restore - mov [reposition],1 - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jnz restore_from_fullscreen - or [edi+WDATA.fl_wstate],WSTATE_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 @f - sub eax,[screen_workarea.bottom] - neg eax - mov [edi+WDATA.box.height],eax - @@: - jmp restore_from_fullscreen.clientbox - restore_from_fullscreen: - and [edi+WDATA.fl_wstate],not WSTATE_MAXIMIZED - push [edi+WDATA.box.height] - push edi ; restore - lea esi, [edx + APPDATA.saved_box] - mov ecx,4 - cld - rep movsd - pop edi - pop eax - test [edi+WDATA.fl_wstate],WSTATE_ROLLEDUP - jz @f - mov [edi+WDATA.box.height],eax - @@: - .clientbox: - call set_window_clientbox - - no_fullscreen_restore: - - mov eax,[edi+WDATA.box.top] ; check Y inside screen - add eax,[edi+WDATA.box.height] - cmp eax,[Screen_Max_Y] - jbe no_window_sizing - mov eax,[edi+WDATA.box.left] ; check X inside screen - add eax,[edi+WDATA.box.width] - cmp eax,[Screen_Max_X] - jbe no_window_sizing - mov eax,[Screen_Max_X] - sub eax,[edi+WDATA.box.width] - mov [edi+WDATA.box.left],eax - mov eax,[Screen_Max_Y] - sub eax,[edi+WDATA.box.height] - mov [edi+WDATA.box.top],eax - call set_window_clientbox - no_window_sizing: - - popad - - cmp [reposition],0 - je retwm - - mov [DONT_DRAW_MOUSE],byte 1 ; no mouse - - - push eax ebx ecx edx - 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 eax,[oldc+BOX.left] - mov ebx,[oldc+BOX.top] - mov ecx,[oldc+BOX.width] - mov edx,[oldc+BOX.height] - add ecx,eax - add edx,ebx - call calculatescreen - pop edx ecx ebx eax - - mov eax,edi - call redrawscreen - - - mov [edi+WDATA.fl_redraw],1 - - mov ecx,100 ; wait to avoid mouse residuals - waitre2: - mov [DONT_DRAW_MOUSE],byte 1 - call checkidle - cmp [edi+WDATA.fl_redraw],0 - jz retwm - loop waitre2 - - retwm: - - mov [DONT_DRAW_MOUSE],byte 0 ; mouse pointer - mov [MOUSE_BACKGROUND],byte 0 ; no mouse under - mov [MOUSE_DOWN],byte 0 ; react to mouse up/down - -; mov esi,window_moved -; call sys_msg_board_str - - popad - - ret - - -uglobal - add_window_data dd 0 - do_resize_from_corner db 0x0 - reposition db 0x0 - latest_window_touch dd 0x0 - latest_window_touch_delta dd 0x0 - - do_resize db 0x0 - - oldc dd 0x0,0x0,0x0,0x0 - - dlx dd 0x0 - dly dd 0x0 - dlxe dd 0x0 - dlye dd 0x0 - - npx dd 0x0 - npy dd 0x0 - npxe dd 0x0 - npye dd 0x0 - - mpx dd 0x0 - mpy dd 0x0 -endg - - -; draw negative window frames -drawwindowframes2: - pushad - cli - jmp drawwindowframes.do -drawwindowframes: - pushad - cli - - test [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED - jnz .ret - mov eax, [npx] - cmp eax, [edi+WDATA.box.left] - jnz .nowndframe - mov eax, [npxe] - cmp eax, [edi+WDATA.box.width] - jnz .nowndframe - mov eax, [npy] - cmp eax, [edi+WDATA.box.top] - jnz .nowndframe - mov eax, [npye] - cmp eax, [edi+WDATA.box.height] - jnz .nowndframe - xor [edi+WDATA.fl_wdrawn], 2 - test [edi+WDATA.fl_wdrawn], 4 - jnz .ret - -.nowndframe: -.do: - mov edi, 1 - mov ecx, 0x01000000 - mov eax,[npx] - shl eax,16 - add eax,[npx] - add eax,[npxe] - add eax,65536*1-1 - mov ebx,[npy] - shl ebx,16 - add ebx,[npy] - call [draw_line] - - mov eax,[npx] - shl eax,16 - add eax,[npx] - add eax,[npxe] - add eax,65536*1-1 - mov ebx,[npy] - add ebx,[npye] - shl ebx,16 - add ebx,[npy] - add ebx,[npye] - call [draw_line] - - mov eax,[npx] - shl eax,16 - add eax,[npx] - mov ebx,[npy] - shl ebx,16 - add ebx,[npy] - add ebx,[npye] - call [draw_line] - - mov eax,[npx] - add eax,[npxe] - shl eax,16 - add eax,[npx] - add eax,[npxe] - mov ebx,[npy] - shl ebx,16 - add ebx,[npy] - add ebx,[npye] - call [draw_line] - -.ret: - sti - popad - ret - - - -random_shaped_window: - -; -; eax = 0 giving address of data area -; ebx address -; eax = 1 shape area scale -; ebx 2^ebx scale - - test eax, eax - jne rsw_no_address - mov eax,[current_slot] - mov [eax+APPDATA.wnd_shape],ebx -rsw_no_address: - - cmp eax,1 - jne rsw_no_scale - mov eax,[current_slot] - mov byte [eax+APPDATA.wnd_shape_scale], bl -rsw_no_scale: - - ret - - +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;; +;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; +;; Distributed under terms of the GNU General Public License ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +$Revision$ + + +;============================================================================== +;///// public functions /////////////////////////////////////////////////////// +;============================================================================== + +macro FuncTable name, [label] +{ + common + align 4 + \label name#.ftable dword + forward + dd name#.#label + common + name#.sizeof.ftable = $ - name#.ftable +} + +iglobal + FuncTable syscall_display_settings, \ + 00, 01, 02, 03, 04, 05, 06, 07, 08 +endg + +uglobal + common_colours rd 32 + new_window_starting dd ? + latest_window_touch dd ? + latest_window_touch_delta dd ? + old_window_pos BOX + new_window_pos BOX + draw_limits RECT + bPressedMouseXY_W db ? + do_resize db ? + do_resize_from_corner db ? + reposition db ? +endg + +align 4 +;------------------------------------------------------------------------------ +syscall_display_settings: ;///// system function 48 /////////////////////////// +;------------------------------------------------------------------------------ +;; Redraw screen: +;< ebx = 0 +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set button style: +;< ebx = 1 +;< ecx = 0 (flat) or 1 (with gradient) +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set system color palette: +;< ebx = 2 +;< ecx = pointer to color table +;< edx = size of color table +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get system color palette: +;< ebx = 3 +;< ecx = pointer to color table buffer +;< edx = size of color table buffer +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get skinned caption height: +;< ebx = 4 +;> eax = height in pixels +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get screen working area: +;< ebx = 5 +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set screen working area: +;< ebx = 6 +;< ecx = pack[16(left), 16(right)] +;< edx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Get skin margins: +;< ebx = 7 +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set skin: +;< ebx = 8 +;< ecx = pointer to FileInfoBlock struct +;> eax = FS error code +;------------------------------------------------------------------------------ + cmp ebx, .sizeof.ftable / 4 + ja @f + jmp [.ftable + ebx * 4] + @@: ret + + +align 4 +syscall_display_settings.00: + xor eax, eax + inc ebx + cmp [windowtypechanged], ebx + jne .exit + mov [windowtypechanged], eax + + jmp syscall_display_settings._.redraw_whole_screen + + .exit: + ret + +align 4 +syscall_display_settings.01: + and ecx, 1 + cmp ecx, [buttontype] + je .exit + mov [buttontype], ecx + mov [windowtypechanged], ebx + + .exit: + ret + +align 4 +syscall_display_settings.02: + dec ebx + mov esi, ecx + and edx, 127 + mov edi, common_colours + mov ecx, edx + rep movsb + mov [windowtypechanged], ebx + ret + +align 4 +syscall_display_settings.03: + mov edi, ecx + and edx, 127 + mov esi, common_colours + mov ecx, edx + rep movsb + ret + +align 4 +syscall_display_settings.04: + mov eax, [_skinh] + mov [esp + 32], eax + ret + +align 4 +syscall_display_settings.05: + mov eax, [screen_workarea.left - 2] + mov ax, word[screen_workarea.right] + mov [esp + 32], eax + mov eax, [screen_workarea.top - 2] + mov ax, word[screen_workarea.bottom] + mov [esp + 20], eax + ret + +align 4 +syscall_display_settings.06: + xor esi, esi + + mov edi, [Screen_Max_X] + 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, [Screen_Max_Y] + 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 .exit + + call repos_windows + jmp syscall_display_settings._.calculate_whole_screen + + .exit: + ret + +align 4 +syscall_display_settings.07: + mov eax, [_skinmargins + 0] + mov [esp + 32], eax + mov eax, [_skinmargins + 4] + mov [esp + 20], eax + ret + +align 4 +syscall_display_settings.08: + mov ebx, ecx + call read_skin_file + mov [esp + 32], eax + test eax, eax + jnz .exit + + call syscall_display_settings._.calculate_whole_screen + jmp syscall_display_settings._.redraw_whole_screen + + .exit: + ret + +syscall_display_settings._.calculate_whole_screen: + xor eax, eax + xor ebx, ebx + mov ecx, [Screen_Max_X] + mov edx, [Screen_Max_Y] + jmp calculatescreen + +syscall_display_settings._.redraw_whole_screen: + xor eax, eax + mov [draw_limits.left], eax + mov [draw_limits.top], eax + mov eax, [Screen_Max_X] + mov [draw_limits.right], eax + mov eax, [Screen_Max_Y] + mov [draw_limits.bottom], eax + mov eax, window_data + jmp redrawscreen + +align 4 +;------------------------------------------------------------------------------ +syscall_set_window_shape: ;///// system function 50 /////////////////////////// +;------------------------------------------------------------------------------ +;; Set window shape address: +;> eax = 0 +;> ebx = shape data address +; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +;; Set window shape scale: +;> eax = 1 +;> ebx = scale power (resulting scale is 2^ebx) +;------------------------------------------------------------------------------ + mov edi, [current_slot] + + test eax, eax + jne .shape_scale + mov [edi + APPDATA.wnd_shape], ebx + + .shape_scale: + dec eax + jnz .exit + mov [edi + APPDATA.wnd_shape_scale], ebx + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +set_window_defaults: ;///////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + push eax ecx + xor eax, eax + mov ecx, WIN_STACK + @@: 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 +;------------------------------------------------------------------------------ +calculatescreen: ;///////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Scan all windows from bottom to top, calling `setscreen` for each one +;? intersecting given screen area +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;------------------------------------------------------------------------------ + push esi + pushfd + cli + + mov esi, 1 + call window._.set_screen + + push ebp + + mov ebp, [TASK_COUNT] + cmp ebp, 1 + jbe .exit + + push edx ecx ebx eax + + .next_window: + movzx edi, word[WIN_POS + esi * 2] + shl edi, 5 + + cmp [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE + je .skip_window + + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .skip_window + + mov eax, [edi + WDATA.box.left] + cmp eax, [esp + RECT.right] + ja .skip_window + mov ebx, [edi + WDATA.box.top] + cmp ebx, [esp + RECT.bottom] + ja .skip_window + mov ecx, [edi + WDATA.box.width] + add ecx, eax + cmp ecx, [esp + RECT.left] + jb .skip_window + mov edx, [edi + WDATA.box.height] + add edx, ebx + cmp edx, [esp + RECT.top] + jb .skip_window + + cmp eax, [esp + RECT.left] + jae @f + mov eax, [esp + RECT.left] + @@: cmp ebx, [esp + RECT.top] + jae @f + mov ebx, [esp + RECT.top] + @@: cmp ecx, [esp + RECT.right] + jbe @f + mov ecx, [esp + RECT.right] + @@: cmp edx, [esp + RECT.bottom] + jbe @f + mov edx, [esp + RECT.bottom] + + @@: push esi + movzx esi, word[WIN_POS + esi * 2] + call window._.set_screen + pop esi + + .skip_window: + inc esi + dec ebp + jnz .next_window + + pop eax ebx ecx edx + + .exit: + pop ebp + popfd + pop esi + ret + +align 4 +;------------------------------------------------------------------------------ +repos_windows: ;/////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + mov ecx, [TASK_COUNT] + mov edi, window_data + WDATA.sizeof * 2 + call force_redraw_background + dec ecx + jle .exit + + .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, [Screen_Max_X] + cmp eax, ebx + jle .fix_vertical + mov eax, [edi + WDATA.box.width] + sub eax, ebx + jle @f + mov [edi + WDATA.box.width], ebx + @@: sub ebx, [edi + WDATA.box.width] + mov [edi + WDATA.box.left], ebx + + .fix_vertical: + mov eax, [edi + WDATA.box.top] + add eax, [edi + WDATA.box.height] + mov ebx, [Screen_Max_Y] + cmp eax, ebx + jle .fix_client_box + mov eax, [edi + WDATA.box.height] + sub eax, ebx + jle @f + mov [edi + WDATA.box.height], ebx + @@: sub ebx, [edi + WDATA.box.height] + mov [edi + WDATA.box.top], ebx + jmp .fix_client_box + + .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 + + .fix_client_box: + call set_window_clientbox + + add edi, WDATA.sizeof + loop .next_window + + .exit: + ret + +align 4 +;------------------------------------------------------------------------------ +check_window_position: ;/////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check if window is inside screen area +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + 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, [Screen_Max_X] + cmp ecx, esi + jbe .check_left + mov ecx, esi + mov [edi + WDATA.box.width], esi + + .check_left: + or eax, eax + jg @f + xor eax, eax + jmp .fix_left + @@: add eax, ecx + cmp eax, esi + jle .check_height + mov eax, esi + sub eax, ecx + + .fix_left: + mov [edi + WDATA.box.left], eax + + .check_height: + mov esi, [Screen_Max_Y] + cmp edx, esi + jbe .check_top + mov edx, esi + mov [edi + WDATA.box.height], esi + + .check_top: + or ebx, ebx + jg @f + xor ebx, ebx + jmp .fix_top + @@: add ebx, edx + cmp ebx, esi + jle .exit + mov ebx, esi + sub ebx, edx + + .fix_top: + mov [edi + WDATA.box.top], ebx + + .exit: + pop esi edx ecx ebx eax + ret + +align 4 +;------------------------------------------------------------------------------ +sys_window_mouse: ;//////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? +;------------------------------------------------------------------------------ + push eax + + mov eax, [timer_ticks] + cmp [new_window_starting], eax + jb .exit + + mov byte[MOUSE_BACKGROUND], 0 + mov byte[DONT_DRAW_MOUSE], 0 + + mov [new_window_starting], eax + + .exit: + pop eax + ret + +align 4 +;------------------------------------------------------------------------------ +draw_rectangle: ;////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = pack[16(left), 16(right)] +;> ebx = pack[16(top), 16(bottom)] +;> esi = color +;------------------------------------------------------------------------------ + push eax ebx ecx edi + + xor edi, edi + + .flags_set: + push ebx + + ; set line color + mov ecx, esi + + ; draw top border + rol ebx, 16 + push ebx + rol ebx, 16 + pop bx + call [draw_line] + + ; draw bottom border + mov ebx, [esp - 2] + pop bx + call [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] + + ; draw right border + mov eax, [esp - 2] + pop ax + call [draw_line] + + pop edi ecx ebx eax + ret + + .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 + @@: push ebx + + xor edi, edi + + .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 + @@: and ecx, 0x00ffffff + call [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? + 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, 1 + mov ebx, 21 + mov ecx, [esi + WDATA.box.width] + mov edx, [esi + WDATA.box.height] + call [drawbar] + + .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 + @@: push ebx + + xor edi, edi + + .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 + @@: test ecx, 0x80000000 + jz @f + sub ecx, 0x00040404 + @@: mov [esi + WDATA.cl_titlebar], ecx + and ecx, 0x00ffffff + call [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] + + .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] + + .exit: + popad + ret + +align 4 +;------------------------------------------------------------------------------ +waredraw: ;//////////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Activate window, redrawing if necessary +;------------------------------------------------------------------------------ + ; 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 + mov byte[MOUSE_DOWN], 1 + call window._.window_activate + + pushad + mov edi, [TASK_COUNT] + movzx esi, word[WIN_POS + edi * 2] + shl esi, 5 + 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, [TASK_COUNT] + movzx esi, word[WIN_POS + edi * 2] + call window._.set_screen + popad + + ; tell application to redraw itself + mov [edi + WDATA.fl_redraw], 1 + mov byte[MOUSE_DOWN], 0 + ret + + .do_not_draw: + ; no it's not, just activate the window + call window._.window_activate + mov byte[MOUSE_DOWN], 0 + mov byte[MOUSE_BACKGROUND], 0 + mov byte[DONT_DRAW_MOUSE], 0 + ret + +align 4 +;------------------------------------------------------------------------------ +minimize_window: ;///////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = window number on screen +;------------------------------------------------------------------------------ +;# corrupts [dl*] +;------------------------------------------------------------------------------ + push edi + pushfd + cli + + ; is it already minimized? + movzx edi, word[WIN_POS + eax * 2] + shl edi, 5 + 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 + 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 + call calculatescreen + xor esi, esi + xor eax, eax + call redrawscreen + + pop esi edx ecx ebx eax + + .exit: + popfd + pop edi + ret + +align 4 +;------------------------------------------------------------------------------ +restore_minimized_window: ;//////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> eax = window number on screen +;------------------------------------------------------------------------------ +;# corrupts [dl*] +;------------------------------------------------------------------------------ + pushad + pushfd + cli + + ; is it already restored? + movzx esi, word[WIN_POS + eax * 2] + mov edi, esi + shl edi, 5 + 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, [TASK_COUNT] + jz @f + mov ebp, calculatescreen + @@: 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 + + mov byte[MOUSE_BACKGROUND], 0 + + .exit: + popfd + popad + ret + +align 4 +;------------------------------------------------------------------------------ +checkwindows: ;//////////////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check for user-initiated window operations +;------------------------------------------------------------------------------ + pushad + + ; do we have window minimize/restore request? + cmp [window_minimize], 0 + je .check_for_mouse_buttons_state + + ; okay, minimize or restore top-most window and exit + mov eax, [TASK_COUNT] + mov bl, 0 + xchg [window_minimize], bl + dec bl + jnz @f + call minimize_window + jmp .check_for_mouse_buttons_state + @@: call restore_minimized_window + + .check_for_mouse_buttons_state: + ; do we have any mouse buttons pressed? + cmp byte[BTN_DOWN], 0 + jne .mouse_buttons_pressed + + mov [bPressedMouseXY_W], 0 + jmp .exit + + .mouse_buttons_pressed: + ; yes we do, iterate and ... + mov esi, [TASK_COUNT] + inc esi + + cmp [bPressedMouseXY_W], 1 + ja .next_window + inc [bPressedMouseXY_W] + jnc .next_window + push dword[MOUSE_X] + pop dword[mx] + + .next_window: + cmp esi, 2 + jb .exit + + dec esi + + ; is that window not minimized? + movzx edi, word[WIN_POS + esi * 2] + shl edi, 5 + add edi, window_data + test [edi + WDATA.fl_wstate], WSTATE_MINIMIZED + jnz .next_window + + movzx eax, [mx] + movzx ebx, [my] + + ; is the cursor inside screen bounds of that window? + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + cmp eax, ecx + jl .next_window + cmp ebx, edx + jl .next_window + add ecx, [edi + WDATA.box.width] + add edx, [edi + WDATA.box.height] + cmp eax, ecx + jge .next_window + cmp ebx, edx + jge .next_window + + ; is that a top-most (which means active) window? + cmp esi, [TASK_COUNT] + je .check_for_moving_or_resizing + + ; no it's not, did we just press mouse button down above it or was it + ; already pressed before? + cmp [bPressedMouseXY_W], 1 + ja .exit + + ; okay, we just pressed the button, activate this window and exit + lea esi, [WIN_POS + esi * 2] + call waredraw + jmp .exit + + .check_for_moving_or_resizing: + ; is that window movable? + test byte[edi + WDATA.cl_titlebar + 3], 0x01 + jnz .exit + + ; yes it is, is it rolled up? + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + jnz .check_for_cursor_on_caption + + ; no it's not, can it be resized then? + mov [do_resize_from_corner], 0 + mov dl, [edi + WDATA.fl_wstyle] + and dl, 0x0f + cmp dl, 0x00 + je .check_for_cursor_on_caption + cmp dl, 0x01 + je .check_for_cursor_on_caption + cmp dl, 0x04 + je .check_for_cursor_on_caption + + ; are we going to resize it? + mov edx, [edi + WDATA.box.top] + add edx, [edi + WDATA.box.height] + sub edx, 6 + cmp ebx, edx + jl .check_for_cursor_on_caption + + ; yes we do, remember that + mov [do_resize_from_corner], 1 + jmp .set_move_resize_flag + + .check_for_cursor_on_caption: + ; is the cursor inside window titlebar? + push eax + call window._.get_titlebar_height + add eax, [edi + WDATA.box.top] + cmp ebx, eax + pop eax + jge .exit + + ; calculate duration between two clicks + mov ecx, [timer_ticks] + mov edx, ecx + sub edx, [latest_window_touch] + mov [latest_window_touch], ecx + mov [latest_window_touch_delta], edx + + .set_move_resize_flag: + mov cl, [BTN_DOWN] + mov [do_resize], cl + + mov ecx, [edi + WDATA.box.left] + mov edx, [edi + WDATA.box.top] + + push ecx edx + mov [draw_limits.left], ecx + mov [draw_limits.top], edx + add ecx, [edi + WDATA.box.width] + add edx, [edi + WDATA.box.height] + mov [draw_limits.right], ecx + mov [draw_limits.bottom], edx + pop edx ecx + + ; calculate window-relative cursor coordinates + sub eax, ecx + sub ebx, edx + + push dword[MOUSE_X] + pop dword[WIN_TEMP_XY] + + ; save old window coordinates + push eax + mov eax, [edi + WDATA.box.left] + mov [old_window_pos.left], eax + mov [new_window_pos.left], eax + mov eax, [edi + WDATA.box.top] + mov [old_window_pos.top], eax + mov [new_window_pos.top], eax + mov eax, [edi + WDATA.box.width] + mov [old_window_pos.width], eax + mov [new_window_pos.width], eax + mov eax, [edi + WDATA.box.height] + mov [old_window_pos.height], eax + mov [new_window_pos.height], eax + pop eax + + ; draw negative moving/sizing frame + call window._.draw_window_frames + + mov [reposition], 0 + mov byte[MOUSE_DOWN], 1 + + .next_mouse_state_check: + ; process OS events + mov byte[DONT_DRAW_MOUSE], 1 + call checkidle + call checkVga_N13 + mov byte[MOUSE_BACKGROUND], 0 + call [draw_pointer] + pushad + call stack_handler + popad + + ; did cursor position change? + mov esi, [WIN_TEMP_XY] + cmp esi, [MOUSE_X] + je .check_for_new_mouse_buttons_state + + ; yes it did, calculate window-relative cursor coordinates + movzx ecx, word[MOUSE_X] + movzx edx, word[MOUSE_Y] + sub ecx, eax + sub edx, ebx + + push eax ebx + + ; we're going to draw new frame, erasing the old one + call window._.draw_window_frames + + ; are we moving it right now? + cmp [do_resize_from_corner], 0 + jne .resize_window + + ; yes we do, check if it's inside the screen area + mov eax, [Screen_Max_X] + mov ebx, [Screen_Max_Y] + + mov [new_window_pos.left], 0 + or ecx, ecx + jle .check_for_new_vert_cursor_pos + mov [reposition], 1 + sub eax, [new_window_pos.width] + mov [new_window_pos.left], eax + cmp ecx, eax + jge .check_for_new_vert_cursor_pos + mov [new_window_pos.left], ecx + + .check_for_new_vert_cursor_pos: + mov [new_window_pos.top], 0 + or edx, edx + jle .draw_new_window_frame + mov [reposition], 1 + sub ebx, [new_window_pos.height] + mov [new_window_pos.top], ebx + cmp edx, ebx + jge .draw_new_window_frame + mov [new_window_pos.top], edx + jmp .draw_new_window_frame + + .resize_window: + push eax ebx edx + + mov edx, edi + sub edx, window_data + lea edx, [SLOT_BASE + edx * 8] + + movzx eax, word[MOUSE_X] + cmp eax, [edi + WDATA.box.left] + jb .fix_new_vert_size + sub eax, [edi + WDATA.box.left] + cmp eax, 32 + jge @f + mov eax, 32 + @@: mov [new_window_pos.width], eax + + .fix_new_vert_size: + call window._.get_rolledup_height + mov ebx, eax + movzx eax, word[MOUSE_Y] + cmp eax, [edi + WDATA.box.top] + jb .set_reposition_flag + sub eax, [edi + WDATA.box.top] + cmp eax, ebx + jge @f + mov eax, ebx + @@: mov [new_window_pos.height], eax + + .set_reposition_flag: + mov [reposition], 1 + + pop edx ebx eax + + .draw_new_window_frame: + pop ebx eax + + ; draw new window moving/sizing frame + call window._.draw_window_frames + + mov esi, [MOUSE_X] + mov [WIN_TEMP_XY], esi + + .check_for_new_mouse_buttons_state: + ; did user release mouse button(s)? + cmp byte[BTN_DOWN], 0 + jne .next_mouse_state_check + + ; yes he did, moving/sizing is over + mov byte[DONT_DRAW_MOUSE], 1 + mov cl, 0 + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jnz .check_other_actions + + mov cl, [reposition] + + ; draw negative frame once again to hide it + call window._.draw_window_frames + + ; save new window bounds + mov eax, [new_window_pos.left] + mov [edi + WDATA.box.left], eax + mov eax, [new_window_pos.top] + mov [edi + WDATA.box.top], eax + mov eax, [new_window_pos.width] + mov [edi + WDATA.box.width], eax + mov eax, [new_window_pos.height] + mov [edi + WDATA.box.height], eax + call set_window_clientbox + + cmp cl, 1 + jne .check_other_actions + push esi edi ecx + mov esi, edi + mov ecx, 2 + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED + jnz @f + add ecx, 2 + @@: sub edi, window_data + shr edi, 5 + shl edi, 8 + add edi, SLOT_BASE + APPDATA.saved_box + cld + rep movsd + pop ecx edi esi + + .check_other_actions: + mov [reposition], cl + + pushad + + mov dl, [edi + WDATA.fl_wstyle] + and dl, 0x0f + cmp dl, 0x00 + je .check_if_window_fits_screen + cmp dl, 0x01 + je .check_if_window_fits_screen + + cmp cl, 1 + je .no_window_sizing + mov edx, edi + sub edx, window_data + shr edx, 5 + shl edx, 8 + add edx, SLOT_BASE + + ; did we right-click on titlebar? + cmp [do_resize], 2 + jne .check_maximization_request + + ; yes we did, toggle normal/rolled up window state + xor [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + mov [reposition], 1 + + ; calculate and set appropriate window height + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + jz @f + call window._.get_rolledup_height + jmp .set_new_window_height + @@: mov eax, [edx + APPDATA.saved_box.height] + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jz .set_new_window_height + mov eax, [screen_workarea.bottom] + sub eax, [screen_workarea.top] + + .set_new_window_height: + mov [edi + WDATA.box.height], eax + add eax, [edi + WDATA.box.top] + cmp eax, [Screen_Max_Y] + jbe @f + mov eax, [Screen_Max_Y] + sub eax, [edi + WDATA.box.height] + mov [edi + WDATA.box.top], eax + @@: call check_window_position + call set_window_clientbox + + .check_maximization_request: + ; can window change its height? + push edx + mov dl, [edi + WDATA.fl_wstyle] + and dl, 0x0f + cmp dl, 0x04 + pop edx + je .check_if_window_fits_screen + + ; was it really a maximize/restore request? + cmp [do_resize], 1 + jne .check_if_window_fits_screen + cmp [do_resize_from_corner], 0 + jne .check_if_window_fits_screen + cmp [latest_window_touch_delta], 50 + jg .check_if_window_fits_screen + + ; yes is was, toggle normal/maximized window state + xor [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + mov [reposition], 1 + + ; calculate and set appropriate window bounds + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jz .restore_normal_window_size + 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 .calculate_window_client_area + sub eax, [screen_workarea.bottom] + neg eax + mov [edi + WDATA.box.height], eax + jmp .calculate_window_client_area + + .restore_normal_window_size: + push [edi + WDATA.box.height] + push edi + lea esi, [edx + APPDATA.saved_box] + mov ecx, 4 + cld + rep movsd + pop edi + pop eax + test [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP + jz .calculate_window_client_area + mov [edi + WDATA.box.height], eax + + .calculate_window_client_area: + call set_window_clientbox + + .check_if_window_fits_screen: + ; does window fit into screen area? + mov eax, [edi + WDATA.box.top] + add eax, [edi + WDATA.box.height] + cmp eax, [Screen_Max_Y] + jbe .no_window_sizing + mov eax, [edi + WDATA.box.left] + add eax, [edi + WDATA.box.width] + cmp eax, [Screen_Max_X] + jbe .no_window_sizing + + ; no it doesn't, fix that + mov eax, [Screen_Max_X] + sub eax, [edi + WDATA.box.width] + mov [edi + WDATA.box.left], eax + mov eax, [Screen_Max_Y] + sub eax, [edi + WDATA.box.height] + mov [edi + WDATA.box.top], eax + call set_window_clientbox + + .no_window_sizing: + popad + + ; did somethins actually change its place? + cmp [reposition], 0 + je .reset_vars + + mov byte[DONT_DRAW_MOUSE], 1 + + push eax ebx ecx edx + + ; recalculate screen buffer at new position + 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 + + ; recalculate screen buffer at old position + mov eax, [old_window_pos.left] + mov ebx, [old_window_pos.top] + mov ecx, [old_window_pos.width] + mov edx, [old_window_pos.height] + add ecx, eax + add edx, ebx + call calculatescreen + + pop edx ecx ebx eax + + mov eax, edi + call redrawscreen + + ; tell window to redraw itself + mov [edi + WDATA.fl_redraw], 1 + + ; wait a bit for window to redraw itself + mov ecx, 100 + + .next_idle_cycle: + mov byte[DONT_DRAW_MOUSE], 1 + call checkidle + cmp [edi + WDATA.fl_redraw], 0 + jz .reset_vars + loop .next_idle_cycle + + .reset_vars: + mov byte[DONT_DRAW_MOUSE], 0 ; mouse pointer + mov byte[MOUSE_BACKGROUND], 0 ; no mouse under + mov byte[MOUSE_DOWN], 0 ; react to mouse up/down + + .exit: + popad + ret + +;============================================================================== +;///// private functions ////////////////////////////////////////////////////// +;============================================================================== + +align 4 +;------------------------------------------------------------------------------ +window._.get_titlebar_height: ;//////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov al, [edi + WDATA.fl_wstyle] + and al, 0x0f + cmp al, 0x03 + jne @f + mov eax, [_skinh] + ret + @@: mov eax, 21 + ret + +align 4 +;------------------------------------------------------------------------------ +window._.get_rolledup_height: ;//////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov al, [edi + WDATA.fl_wstyle] + and al, 0x0f + cmp al, 0x03 + jb @f + mov eax, [_skinh] + add eax, 3 + ret + @@: or al, al + jnz @f + mov eax, 21 + ret + @@: mov eax, 21 + 2 + ret + +align 4 +;------------------------------------------------------------------------------ +window._.set_screen: ;///////////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Reserve window area in screen buffer +;------------------------------------------------------------------------------ +;> eax = left +;> ebx = top +;> ecx = right +;> edx = bottom +;> esi = process number +;------------------------------------------------------------------------------ +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, 5 + cmp [window_data + edi + WDATA.box.width], 0 + jnz .check_for_shaped_window + cmp [window_data + edi + WDATA.box.height], 0 + jz .exit + + .check_for_shaped_window: + mov edi, esi + shl edi, 8 + 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 + mov edi, [Screen_Max_X] + inc edi + imul edi, ebx + add edi, eax + add edi, [_WinMapAddress] + mov eax, esi + + .next_line: + push ecx + rep stosb + pop ecx + add edi, [Screen_Max_X] + inc edi + sub edi, ecx + dec edx + jnz .next_line + + jmp .exit + + .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, [Screen_Max_X] ; screen_sx + inc eax + imul eax, ebx + add eax, [esp] + add eax, [_WinMapAddress] + 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, 5 + 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] + + .ff_new_y: + mov edx, [ff_x] + + .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 -- + @@: inc ebp + inc edx + cmp edx, [ff_xsz] + jb .ff_new_x + + sub ebp, [ff_xsz] + add ebp, [ff_x] + add ebp, [Screen_Max_X] ; screen.x + inc ebp + inc ebx + cmp ebx, [ff_ysz] + jb .ff_new_y + + add esp, 24 + + .exit: + popad + ret + + .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 +;------------------------------------------------------------------------------ +window._.window_activate: ;//////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Activate window +;------------------------------------------------------------------------------ +;> esi = pointer to WIN_POS+ window data +;------------------------------------------------------------------------------ + push eax ebx + + ; if type of current active window is 3 or 4, it must be redrawn + mov eax, [TASK_COUNT] + movzx eax, word[WIN_POS + eax * 2] + shl eax, 5 + add eax, window_data + mov bl, [eax + WDATA.fl_wstyle] + and bl, 0x0f + cmp bl, 0x03 + je .set_window_redraw_flag + cmp bl, 0x04 + je .set_window_redraw_flag + jmp .move_others_down + + .set_window_redraw_flag: + mov [eax + WDATA.fl_redraw], 1 + + .move_others_down: + ; ax <- process no + movzx eax, word[esi] + ; ax <- position in window stack + movzx eax, word[WIN_STACK + eax * 2] + + ; drop others + xor ebx, ebx + + .next_stack_window: + cmp ebx, [TASK_COUNT] + jae .move_self_up + inc ebx + cmp [WIN_STACK + ebx * 2], ax + jbe .next_stack_window + dec word[WIN_STACK + ebx * 2] + jmp .next_stack_window + + .move_self_up: + movzx eax, word[esi] + ; number of processes + mov bx, [TASK_COUNT] + ; this is the last (and the upper) + mov [WIN_STACK + eax * 2], bx + + ; update on screen - window stack + xor ebx, ebx + + .next_window_pos: + cmp ebx, [TASK_COUNT] + jae .reset_vars + inc ebx + movzx eax, word[WIN_STACK + ebx * 2] + mov [WIN_POS + eax * 2], bx + jmp .next_window_pos + + .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 +;------------------------------------------------------------------------------ +window._.check_window_draw: ;////////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Check if window is necessary to draw +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + mov cl, [edi + WDATA.fl_wstyle] + and cl, 0x0f + cmp cl, 0x03 + je .exit.redraw ; window type 3 + cmp cl, 0x04 + je .exit.redraw ; window type 4 + + push eax ebx edx esi + + mov eax, edi + sub eax, window_data + shr eax, 5 + + ; esi = process number + + 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 + + .next_window: + add esi, 2 + + mov eax, [TASK_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, 5 + cmp [CURRENT_TASK + edx + TASKDATA.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 + + .exit.redraw: + xor ecx, ecx + inc ecx + ret + + .exit.no_redraw: + pop esi edx ebx eax + xor ecx, ecx + ret + +align 4 +;------------------------------------------------------------------------------ +window._.draw_window_frames: ;///////////////////////////////////////////////// +;------------------------------------------------------------------------------ +;? Draw negative window frames +;------------------------------------------------------------------------------ +;> edi = pointer to WDATA +;------------------------------------------------------------------------------ + push eax + cli + + test [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED + jnz .exit + mov eax, [new_window_pos.left] + cmp eax, [edi + WDATA.box.left] + jnz .draw + mov eax, [new_window_pos.width] + cmp eax, [edi + WDATA.box.width] + jnz .draw + mov eax, [new_window_pos.top] + cmp eax, [edi + WDATA.box.top] + jnz .draw + mov eax, [new_window_pos.height] + cmp eax, [edi + WDATA.box.height] + jnz .draw + xor [edi + WDATA.fl_wdrawn], 2 + + .draw: + push ebx esi + mov eax, [new_window_pos.left - 2] + mov ax, word[new_window_pos.left] + add ax, word[new_window_pos.width] + mov ebx, [new_window_pos.top - 2] + mov bx, word[new_window_pos.top] + add bx, word[new_window_pos.height] + mov esi, 0x01000000 + call draw_rectangle.forced + pop esi ebx + + .exit: + sti + pop eax + ret + + .forced: + push eax + cli + jmp .draw diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 6d463d96ed..3d95c6bf05 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -684,7 +684,7 @@ end if mov esi,boot_windefs call boot_log - call setwindowdefaults + call set_window_defaults ; SET BACKGROUND DEFAULTS @@ -3348,10 +3348,10 @@ sys_window_move: pop eax add ecx,eax add edx,ebx - mov [dlx],eax ; save for drawlimits - mov [dly],ebx - mov [dlxe],ecx - mov [dlye],edx + mov [draw_limits.left],eax ; save for drawlimits + mov [draw_limits.top],ebx + mov [draw_limits.right],ecx + mov [draw_limits.bottom],edx call calculatescreen mov [edi + WDATA.fl_redraw], 1 ; flag the process as redraw @@ -3667,11 +3667,11 @@ redrawscreen: add ecx,eax add edx,ebx - mov ecx,[dlye] ; ecx = area y end ebx = window y start + mov ecx,[draw_limits.bottom] ; ecx = area y end ebx = window y start cmp ecx,ebx jb ricino - mov ecx,[dlxe] ; ecx = area x end eax = window x start + mov ecx,[draw_limits.right] ; ecx = area x end eax = window x start cmp ecx,eax jb ricino @@ -3682,11 +3682,11 @@ redrawscreen: add ecx, eax add edx, ebx - mov eax,[dly] ; eax = area y start edx = window y end + mov eax,[draw_limits.top] ; eax = area y start edx = window y end cmp edx,eax jb ricino - mov eax,[dlx] ; eax = area x start ecx = window x end + mov eax,[draw_limits.left] ; eax = area x start ecx = window x end cmp ecx,eax jb ricino @@ -3700,22 +3700,22 @@ redrawscreen: test al,al jz .az lea eax,[edi+draw_data-window_data] - mov ebx,[dlx] + mov ebx,[draw_limits.left] cmp ebx,[eax+RECT.left] jae @f mov [eax+RECT.left],ebx @@: - mov ebx,[dly] + mov ebx,[draw_limits.top] cmp ebx,[eax+RECT.top] jae @f mov [eax+RECT.top],ebx @@: - mov ebx,[dlxe] + mov ebx,[draw_limits.right] cmp ebx,[eax+RECT.right] jbe @f mov [eax+RECT.right],ebx @@: - mov ebx,[dlye] + mov ebx,[draw_limits.bottom] cmp ebx,[eax+RECT.bottom] jbe @f mov [eax+RECT.bottom],ebx @@ -3726,13 +3726,13 @@ redrawscreen: mov eax,edi add eax,draw_data-window_data - mov ebx,[dlx] ; set limits + mov ebx,[draw_limits.left] ; set limits mov [eax + RECT.left], ebx - mov ebx,[dly] + mov ebx,[draw_limits.top] mov [eax + RECT.top], ebx - mov ebx,[dlxe] + mov ebx,[draw_limits.right] mov [eax + RECT.right], ebx - mov ebx,[dlye] + mov ebx,[draw_limits.bottom] mov [eax + RECT.bottom], ebx sub eax,draw_data-window_data diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 195c722d4d..542d0597c0 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -98,6 +98,14 @@ struc TASKDATA virtual at 0 TASKDATA TASKDATA end virtual + +TSTATE_RUNNING = 0 +TSTATE_RUN_SUSPENDED = 1 +TSTATE_WAIT_SUSPENDED = 2 +TSTATE_ZOMBIE = 3 +TSTATE_TERMINATING = 4 +TSTATE_WAITING = 5 +TSTATE_FREE = 9 ; structures definition struc WDATA { @@ -109,11 +117,12 @@ struc WDATA { .fl_wstate db ? .fl_wdrawn db ? .fl_redraw db ? + .sizeof: } virtual at 0 WDATA WDATA end virtual -label WDATA.fl_wstyle byte at 0x13 +label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3 struc APPDATA {