;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; 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 ;------------------------------------------------------------------------------ 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_TASK] setz al movzx eax, al push eax call drawwindow_IV jmp window._.draw_window_caption.2 ;-------------------------------------- .exit: ret ;------------------------------------------------------------------------------ syscall_display_settings: ;///// system function 48 /////////////////////////// ;------------------------------------------------------------------------------ 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 ; jnz @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 jnz @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 + 32], eax mov eax, [screen_workarea.top - 2] mov ax, word[screen_workarea.bottom] mov [esp + 20], 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 + 32], eax mov eax, [_skinmargins + 4] mov [esp + 20], eax ret .setSkin: ; in: ecx -> file path string mov ebx, ecx call read_skin_file mov [esp + 32], eax test eax, eax jnz .ret call .calculateScreen jmp .redrawScreen .getFontSmoothing: xor eax, eax mov al, [fontSmoothing] mov [esp + 32], eax ret .setFontSmoothing: mov [fontSmoothing], cl ret .getFontSize: xor eax, eax mov al, [fontSize] mov [esp + 32], 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 + 32 + 4], eax @@: call kernel_free call .calculateScreen jmp .redrawScreen ;------------------------------------------------------------------------------ syscall_set_window_shape: ;///// 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) ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ syscall_move_window: ;///// system function 67 //////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ mov edi, [CURRENT_TASK] shl edi, 5 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 ;------------------------------------------------------------------------------ syscall_window_settings: ;///// system function 71 //////////////////////////// ;------------------------------------------------------------------------------ mov edi, [CURRENT_TASK] shl edi, 5 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 + 0x20 + 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 ;------------------------------------------------------------------------------ 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, [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, 5 ;size of TASKDATA and WDATA = 32 bytes 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, [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, 5 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 ;------------------------------------------------------------------------------ draw_rectangle: ;////////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;> 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 ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ waredraw: ;//////////////////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? Activate window, redrawing if necessary ;------------------------------------------------------------------------------ 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, 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, [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, 5 ; it is a unused slot? cmp dword [edi+CURRENT_TASK+TASKDATA.state], 9 je @f ; it is a hidden thread? lea esi, [edi*8+SLOT_BASE+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 ;------------------------------------------------------------------------------ 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 ; 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 ;------------------------------------------------------------------------------ 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, [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 ;------------------------------------------------------------------------------ sys_window_maximize_handler: ;///////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> esi = process slot ;------------------------------------------------------------------------------ mov edi, esi shl edi, 5 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, 8 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 ;------------------------------------------------------------------------------ sys_window_rollup_handler: ;/////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> esi = process slot ;------------------------------------------------------------------------------ mov edx, esi shl edx, 8 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: ;///////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> eax = old (original) window box ;> esi = process slot ;------------------------------------------------------------------------------ ; mov edi, eax ; call window._.draw_negative_box ; ret ;------------------------------------------------------------------------------ align 4 ;------------------------------------------------------------------------------ sys_window_end_moving_handler: ;/////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> eax = old (original) window box ;> ebx = new (final) window box ;> esi = process slot ;------------------------------------------------------------------------------ ; mov edi, ebx ; call window._.end_moving__box mov edi, esi shl edi, 5 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 ;------------------------------------------------------------------------------ sys_window_moving_handler: ;/////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> eax = old (from previous call) window box ;> ebx = new (current) window box ;> esi = process_slot ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ window._.invalidate_screen: ;////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> eax = old (original) window box ;> ebx = new (final) window box ;> edi = pointer to WDATA struct ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ window._.set_window_box: ;///////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> eax = pointer to BOX struct ;> bl = new window state flags ;> edi = pointer to WDATA struct ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ window._.set_window_clientbox: ;/////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;> edi = pointer to WDATA struct ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ window._.sys_set_window: ;///////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? ;------------------------------------------------------------------------------ ;< edx = pointer to WDATA struct ;------------------------------------------------------------------------------ mov eax, [CURRENT_TASK] shl eax, 5 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_TASK] 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 ;------------------------------------------------------------------------------ window._.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, [_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 mov [edi + WDATA.box.width], esi 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 mov [edi + WDATA.box.left], eax jmp .check_height ;-------------------------------------- align 4 .fix_height_high: mov edx, esi mov [edi + WDATA.box.height], esi 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 mov [edi + WDATA.box.top], ebx jmp .exit ;------------------------------------------------------------------------------ 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 ;-------------------------------------- align 4 @@: 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 ;-------------------------------------- align 4 @@: or al, al jnz @f mov eax, 21 ret ;-------------------------------------- align 4 @@: 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 ;-------------------------------------- align 4 .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 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, 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] ;-------------------------------------- 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 ;------------------------------------------------------------------------------ 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 ebx, [thread_count] ; DEBUGF 1, "K : thread_count (0x%x)\n", ebx movzx ebx, word[WIN_POS + ebx * 2] shl ebx, 5 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 ;------------------------------------------------------------------------------ window._.window_deactivate: ;//////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? Deactivate window ;------------------------------------------------------------------------------ ;> esi = pointer to WIN_POS+ window data ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ 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, 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, 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 ;-------------------------------------- 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_TASK] jne @f inc eax ;-------------------------------------- align 4 @@: mov edx, [CURRENT_TASK] 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_TASK] shl edi, 5 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 ;------------------------------------------------------------------------------ window._.draw_negative_box: ;////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? Draw negative box ;------------------------------------------------------------------------------ ;> edi = pointer to BOX struct ;------------------------------------------------------------------------------ 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 ;------------------------------------------------------------------------------ window._.get_rect: ;///////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? void __fastcall get_window_rect(struct RECT* rc); ;------------------------------------------------------------------------------ ;> ecx = pointer to RECT ;------------------------------------------------------------------------------ mov eax, [TASK_BASE] mov edx, [eax-twdw + WDATA.box.left] mov [ecx+RECT.left], edx add edx, [eax-twdw + WDATA.box.width] mov [ecx+RECT.right], edx mov edx, [eax-twdw + WDATA.box.top] mov [ecx+RECT.top], edx add edx, [eax-twdw + WDATA.box.height] mov [ecx+RECT.bottom], edx ret ;------------------------------------------------------------------------------ align 4 ;------------------------------------------------------------------------------ window._.redraw_top_wnd: ;//////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? redraw all windows one above the window ;------------------------------------------------------------------------------ ;> eax = left ;> ebx = top ;> ecx = right ;> edx = bottom ;> esi = process number ;! corrupted edi ;------------------------------------------------------------------------------ push 0 jmp window._.set_top_wnd.go align 4 ;------------------------------------------------------------------------------ window._.set_top_wnd: ;//////////////////////////////////////////////////////// ;------------------------------------------------------------------------------ ;? call set_screen for all windows one above the window ;------------------------------------------------------------------------------ ;> eax = left ;> ebx = top ;> ecx = right ;> edx = bottom ;> esi = process number ;! corrupted edi ;------------------------------------------------------------------------------ push 1 .go: push esi pushfd cli push ebp mov ebp, [thread_count] cmp ebp, 1 jbe .exit shl esi, 5 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, 5 ;size of TASKDATA and WDATA = 32 bytes 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, [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