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
        jne     @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,0xc000
       @@:
        inc   eax
        add   ecx,2
        mov   [ecx+0x000],ax          ; process no
        mov   [ecx+0x400],ax          ; positions in stack
        cmp   ecx,0xc400-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, [0x3004]        ; number of processes
        cmp     ebp, 1
        jbe     .finish
        align 4
      .new_wnd:
        movzx   edi, word [0xC400 + esi * 2]
        shl     edi, 5

        cmp     [0x3000+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 [0xC400 + 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+0xc400]
        shl   edi, 8
        add   edi, 0x80000  ; 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, [0xFE00] ; 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, [0xFE00]
        inc   edi
        sub   edi, ecx
        dec   edx
        jnz   .new_y
.ret:
 popad
 ret
  .read_byte:
   ;eax - address
   ;esi - slot
        push  eax
        push  ebx
        push  ecx
        push  edx
        mov   edx,eax
        mov   eax,esi
        lea   ebx,[esp+12]
        mov   ecx,1
        call  read_process_memory
        pop   edx
        pop   ecx
        pop   ebx
        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, [0xFE00] ; 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, [0xFE00]  ; screen.x
        inc  ebp
        inc  ebx
        cmp  ebx, [ff_ysz]
        jb   .ff_new_y

        add  esp, 24
popad
ret


display_settings:

;    eax = 0         ; DISPLAY redraw
;          ebx = 0   ; all
;
;    eax = 1         ; BUTTON type
;          ebx = 0   ; flat
;          ebx = 1   ; 3D
;    eax = 2         ; set WINDOW colours
;          ebx = pointer to table
;          ecx = number of bytes define
;    eax = 3         ; get WINDOW colours
;          ebx = pointer to table
;          ecx = number of bytes wanted
;    eax = 4         ; get skin height
;          input  : nothing
;          output : eax = skin height in pixel
;    eax = 5         ; get screen workarea
;          input  : nothing
;          output : eax = [left]*65536+[right]
;                   ebx = [top]*65536+[bottom]
;    eax = 6         ; set screen workarea
;          input  : ecx = [left]*65536+[right]
;                   edx = [top]*65536+[bottom]
;          output : nothing
;    eax = 7         ; get skin margins
;          input  : nothing
;          output : eax = [left]*65536+[right]
;                   ebx = [top]*65536+[bottom]
;    eax = 8         ; set window skin
;          input  : ecx = pointer to file info block
;          output : eax = FS error code


     pushad

     test eax, eax      ; redraw display
     jnz  dspl0
     test ebx, ebx
     jnz  dspl0
     cmp  [windowtypechanged],dword 1
     jne  dspl00
     mov  [windowtypechanged],dword 0
  redraw_screen_direct:
     mov  [dlx],dword 0
     mov  [dly],dword 0
     mov  eax,[0xfe00]
     mov  [dlxe],eax
     mov  eax,[0xfe04]
     mov  [dlye],eax
     mov  eax,window_data
     call redrawscreen
   dspl00:
     popad
     ret
   dspl0:

     cmp  eax,1       ; button type
     jne  dspl1
     and  ebx,1
     cmp  ebx,[buttontype]
     je   dspl9
     mov  [buttontype],ebx
     mov  [windowtypechanged],dword 1
    dspl9:
     popad
     ret
   dspl1:

     cmp  eax,2       ; set common window colours
     jne  no_com_colours
     mov  [windowtypechanged],dword 1
     mov  esi,[0x3010]
     add  esi,TASKDATA.mem_start
     add  ebx,[esi]
     mov  esi,ebx
     mov  edi,common_colours
     and  ecx,127
     cld
     rep  movsb
     popad
     ret
   no_com_colours:

     cmp  eax,3       ; get common window colours
     jne  no_get_com
     mov  esi,[0x3010]
     add  esi,TASKDATA.mem_start
     add  ebx,[esi]
     mov  edi,ebx
     mov  esi,common_colours
     and  ecx,127
     cld
     rep  movsb
     popad
     ret
   no_get_com:

     cmp  eax,4       ; get skin height
     jne  no_skin_height
     popad
     mov  eax,[_skinh]
     mov  [esp+36],eax
     ret
   no_skin_height:

        cmp     eax,5       ; get screen workarea
        jne     no_get_workarea
        popad
        mov     eax,[screen_workarea.left-2]
        mov     ax,word[screen_workarea.right]
        mov     [esp+36],eax
        mov     eax,[screen_workarea.top-2]
        mov     ax,word[screen_workarea.bottom]
        mov     [esp+24],eax
        ret
   no_get_workarea:

        cmp     eax,6       ; set screen workarea
        jne     no_set_workarea
        movsx   eax,word[esp+16+2]
        movsx   ebx,word[esp+16]
        cmp     eax,ebx
        jge     .lp1
        or      eax,eax;[0xFE00]
        jl      @f
        mov     [screen_workarea.left],eax
    @@: cmp     ebx,[0xFE00]
        jg      .lp1
        mov     [screen_workarea.right],ebx
  .lp1: movsx   eax,word[esp+24+2]
        movsx   ebx,word[esp+24]
        cmp     eax,ebx
        jge     .lp2
        or      eax,eax;[0xFE04]
        jl      @f
        mov     [screen_workarea.top],eax
    @@: cmp     ebx,[0xFE04]
        jg      .lp2
        mov     [screen_workarea.bottom],ebx
  .lp2: call    repos_windows
        mov     eax, 0
        mov     ebx, 0
        mov     ecx, [0xfe00]
        mov     edx, [0xfe04]
    call    calculatescreen
;    jmp    redraw_screen_direct
    .exit:
        popad
        ret
   no_set_workarea:

        cmp     eax,7       ; get skin margins
        jne     no_get_skinmargins
        popad
        mov     eax,dword[_skinmargins+0]
        mov     [esp+36],eax
        mov     eax,dword[_skinmargins+4]
        mov     [esp+24],eax
        ret
   no_get_skinmargins:

        cmp     eax,8       ; set window skin
        jne     no_set_skin
        mov     eax,ebx
        mov     edi,[0x3010]
        add     ebx,[edi+TASKDATA.mem_start]        ; abs start of info block
        pushd   [ebx+0] [ebx+4] [ebx+8] [ebx+12]
        mov     dword[ebx+0],0        ; read
        mov     dword[ebx+4],0        ; from the beginning
        mov     dword[ebx+8],64       ; 32 KBytes maximum
        mov     ecx,skin_data+64*512
        sub     ecx,[edi+0x10]
        mov     dword[ebx+12],ecx     ; destination
        push    eax
        pushad
        call    file_system
        popad
        pop    eax
        popd    [ebx+12] [ebx+8] [ebx+4] [ebx+0]
        cmp     eax,ERROR_SUCCESS
        je      @f
        cmp     eax,ERROR_END_OF_FILE
        jne     .exit
    @@: cmp     [skin_data+64*512+SKIN_HEADER.ident],'SKIN'
        mov     eax,ERROR_UNKNOWN_FS
        jne     .exit
        mov     esi,skin_data+64*512
        mov     edi,skin_data
        mov     ecx,(64*512)/4
        rep     movsd
        call    parse_skin_data
    pushad
        mov     eax, 0
        mov     ebx, 0
        mov     ecx, [0xfe00]
        mov     edx, [0xfe04]
        call    calculatescreen
    popad
        mov     dword[esp+32+36],0
        jmp     redraw_screen_direct
  .exit:
        mov     [esp+32+36],eax
        popad
        ret
   no_set_skin:

     popad
     ret


repos_windows:
        mov     ecx,[0x3004]
        mov     esi,0x20*2
    mov    byte[0x0000fff0],1
        dec     ecx
        jge    @f
        ret
    @@: mov    [esi+WDATA.fl_redraw],1
    test    [esi+WDATA.fl_wstate],WSTATE_MAXIMIZED
        jz      .lp2
        mov     eax,[screen_workarea.left]
        mov     [esi+WDATA.box.left],eax
        sub     eax,[screen_workarea.right]
        neg     eax
        mov     [esi+WDATA.box.width],eax
        mov     eax,[screen_workarea.top]
        mov     [esi+WDATA.box.top],eax
        test    [esi+WDATA.fl_wstate],WSTATE_ROLLEDUP
        jnz     .lp1
        sub     eax,[screen_workarea.bottom]
        neg     eax
        mov     [esi+WDATA.box.height],eax
  .lp1: add     esi,0x20
        loop    @b
        ret
  .lp2: mov     eax,[esi+WDATA.box.left]
        add     eax,[esi+WDATA.box.width]
    mov    ebx,[0x0000fe00]
;    inc    ebx
    cmp    eax,ebx
    jle    .lp4
        mov     eax,[esi+WDATA.box.width]
    sub    eax,ebx
    jle    .lp3
        mov     [esi+WDATA.box.width],ebx
  .lp3: sub     ebx,[esi+WDATA.box.width]
        mov     [esi+WDATA.box.left],ebx
  .lp4: mov     eax,[esi+WDATA.box.top]
        add     eax,[esi+WDATA.box.height]
    mov    ebx,[0x0000fe04]
;    inc    ebx
    cmp    eax,ebx
    jle    .lp6
        mov     eax,[esi+WDATA.box.height]
    sub    eax,ebx
    jle    .lp5
        mov     [esi+WDATA.box.height],ebx
  .lp5: sub     ebx,[esi+WDATA.box.height]
        mov     [esi+WDATA.box.top],ebx
  .lp6: add     esi,0x20
        loop    @b
    ret

uglobal
  common_colours:
     times 128 db 0x0
endg




check_window_position:

    pushad                           ; window inside screen ?

    movzx eax,word [edi+WDATA.box.left]
    movzx ebx,word [edi+WDATA.box.top]
    movzx ecx,word [edi+WDATA.box.width]
    movzx edx,word [edi+WDATA.box.height]

    mov   esi,ecx             ; check x pos
    add   esi,eax
    cmp   esi,[0xfe00]
    jbe   x_pos_ok
    mov   [edi+WDATA.box.left],dword 0
    xor   eax, eax
  x_pos_ok:

    mov   esi,edx             ; check y pos
    add   esi,ebx
    cmp   esi,[0xfe04]
    jbe   y_pos_ok
    mov   [edi+WDATA.box.top],dword 0
    mov   ebx,0
  y_pos_ok:

    mov   esi,ecx             ; check x size
    add   esi,eax
    cmp   esi,[0xfe00]
    jbe   x_size_ok
    mov   ecx,[0xfe00]
    mov   [edi+WDATA.box.width],ecx
  x_size_ok:

    mov   esi,edx             ; check y size
    add   esi,ebx
    cmp   esi,[0xfe04]
    jbe   y_size_ok
    mov   edx,[0xfe04]
    mov   [edi+WDATA.box.height],edx
  y_size_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   [0xfff4],byte 0  ; no mouse background
    mov   [0xfff5],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

        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

        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]
        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
        call  draw_rectangle
        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]
        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, [0x3004]
        movzx eax, word [0xC400 + eax*2]
        shl   eax, 5
        add   eax, window_data
        mov   ebx, [eax + WDATA.cl_workarea]
        and   ebx, 0x0f000000
        cmp   ebx, 0x03000000
        jne   @f
        mov   [eax + WDATA.fl_redraw], byte 1
     @@:

        push   esi
      movzx   eax, word [esi] ; ax <- process no
      movzx   eax, word [0xC000+eax*2] ; ax <- position in window stack

        xor   esi, esi        ; drop others
      waloop:
        cmp   esi, dword [0x3004]
        jae   wacont
        inc   esi
        lea   edi, [0xC000 + 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, [0x3004]  ; number of processes
        mov   [0xC000+eax*2], bx     ; this is the last (and the upper)

        ; update on screen -window stack
        xor   esi, esi
      waloop2:
        mov   edi, [0x3004]
        cmp   esi, edi
        jae   wacont2
        inc   esi
        movzx ebx, word [esi*2 + 0xC000]
        mov   [ebx*2 + 0xC400], si
        jmp   waloop2
      wacont2:
        mov   [0xf400], byte 0           ; empty keyboard buffer
        mov   [0xf500], byte 0           ; empty button buffer
        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

        mov   esi, edi
        sub   esi, window_data
        shr   esi, 5

        ; esi = process number

        movzx eax, word [0xC000 + esi * 2] ; get value of the curr process
        lea   esi, [0xC400 + eax * 2]      ; get address of this process at 0xC400

        push  esi

      .new_check:

        pop   esi
        add   esi, 2
        push  esi

        mov   eax, [0x3004]
        lea   eax, word [0xC400 + eax * 2] ; number of the upper window

        cmp   esi, eax
        ja    .all_wnds_to_top

        movzx eax, word [esi]
        shl   eax, 5
        cmp   [0x3000 + 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   [0xfb44], byte 1     ; do draw mouse
        call  windowactivate

        ; update screen info
        pushad
        mov   edi, [0x3004] ; the last process (number)
        movzx esi, word [0xC400 + 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, [0x3004]
        movzx esi, word [0xC400 + edi * 2]
        call  setscreen
        popad

    mov   [edi + WDATA.fl_redraw], 1  ; redraw flag for app
    mov   [0xfb44],byte 0             ; mouse down checks

        ret

     .do_not_draw:

        popad

        call  windowactivate
        mov   [0xfb44],byte 0  ; mouse down checks
        mov   [0xfff4],byte 0  ; no mouse background
        mov   [0xfff5],byte 0  ; draw mouse
        ret


; eax = window number on screen
; corrupts registers and [dl*]
minimize_window:
        movzx eax, word [0xC400+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 [0xC400+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, [0x3004] ; 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   [0xfff4],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, [0x3004]       ; 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   [0xfb40],byte 0    ; mouse buttons pressed ?
        jne   .mouse_buttons_pressed
        popad
        ret
    .mouse_buttons_pressed:

        mov   esi,[0x3004]
        inc   esi

      cwloop:
        cmp   esi,2
        jb   .exit

        dec   esi
        movzx edi, word [0xC400 + 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

       movzx  eax, word [0xfb0a]
       movzx  ebx, word [0xfb0c]
       
        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, [0x3004]
        cmp   eax, ebx      ; is this window active?
        jz    .move_resize_window

        ; eax = position in windowing stack
        ; redraw must ?
        lea   esi, [0xC400 + esi * 2]
        call  waredraw
        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, 0x02000000
        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, [0xfb40]     ; 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, [0xfb0a]
        mov   [0xf300], esi

        pushad           ; wait for putimages to finish
;        mov   eax,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

        test    [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
        jnz     @f
        call  drawwindowframes
    @@:

        mov   [reposition],0
        mov   [0xfb44],byte 1   ; no reaction to mouse up/down

        ; move window

      newchm:

        mov   [0xfff5],byte 1

        call  checkidle

        call  checkVga_N13

        mov   [0xfff4],byte 0

        call  [draw_pointer]

        pushad
        call   stack_handler
        popad

        mov   esi,[0xf300]
        cmp   esi,[0xfb0a]
        je    cwb

        mov   cx,[0xfb0a]
        mov   dx,[0xfb0c]
        sub   cx,ax
        sub   dx,bx

        push  ax
        push  bx

        test    [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
        jnz     @f
        call  drawwindowframes
    @@:

        mov   ax,[0xfe00]
        mov   bx,[0xfe04]

        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, [0x80000 + edx*8]

        movzx eax,word [0xfb0a]
    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 [0xfb0c]
    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
        test    [edi+WDATA.fl_wstate],WSTATE_MAXIMIZED
        jnz     @f
        call  drawwindowframes
    @@:

        mov   esi,[0xfb0a]
        mov   [0xf300],esi

      cwb:
        cmp   [0xfb40],byte 0
        jne   newchm 
                                     ; new position done
        mov     [0xfff5],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

    @@: 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,0x80000+APPDATA.saved_box
        cld
        rep   movsd
        pop   ecx edi esi
      no_bounds_save:

        pushad                             ; WINDOW SHADE/FULLSCREEN

        cmp   [reposition],1
        je    no_window_sizing
        mov   edx,edi
        sub   edx,window_data
        shr   edx,5
        shl   edx,8
        add   edx,0x80000                 ; 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

      no_window_shade:

        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   no_fullscreen_restore
      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
    @@:

      no_fullscreen_restore:

        mov   eax,[edi+WDATA.box.top]                 ; check Y inside screen
        add   eax,[edi+WDATA.box.height]
        cmp   eax,[0xfe04]
        jbe   no_window_sizing
        mov   eax,[edi+WDATA.box.left]                 ; check X inside screen
        add   eax,[edi+WDATA.box.width]
        cmp   eax,[0xfe00]
        jbe   no_window_sizing
        mov   eax,[0xfe00]
        sub   eax,[edi+WDATA.box.width]
        mov   [edi+WDATA.box.left],eax
        mov   eax,[0xfe04]
        sub   eax,[edi+WDATA.box.height]
        mov   [edi+WDATA.box.top],eax
      no_window_sizing:

        popad

        cmp   [reposition],0
        je    retwm

        mov   [0xfff5],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   [0xfff5],byte 1
        call  checkidle
        cmp     [edi+WDATA.fl_redraw],0
        jz    retwm
        loop  waitre2

      retwm:

        mov   [0xfff5],byte 0 ; mouse pointer
        mov   [0xfff4],byte 0 ; no mouse under
        mov   [0xfb44],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

drawwindowframes:

        pushad

        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]
        mov   ecx,0x01000000
        push  edi
        mov   edi,1
        call  [draw_line]
        pop   edi

        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]
        mov   ecx,0x01000000
        push  edi
        mov   edi,1
        call  [draw_line]
        pop   edi

        mov   eax,[npx]
        shl   eax,16
        add   eax,[npx]
        mov   ebx,[npy]
        shl   ebx,16
        add   ebx,[npy]
        add   ebx,[npye]
        mov   ecx,0x01000000
        push  edi
        mov   edi,1
        call  [draw_line]
        pop   edi

        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]
        mov   ecx,0x01000000
        push  edi
        mov   edi,1
        call  [draw_line]
        mov   edi,[0x3000]
        shl   edi,5
        add   edi,window_data
        mov   [edi+WDATA.fl_wdrawn],byte 1
        pop   edi

        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,[0x3000]
     shl  eax,8

     mov  [eax+0x80000+APPDATA.wnd_shape],ebx
   rsw_no_address:

     cmp  eax,1
     jne  rsw_no_scale
     mov  eax,[0x3000]
     shl  eax,8
     mov  byte [eax+0x80000+APPDATA.wnd_shape_scale], bl
   rsw_no_scale:

     ret


