Subversion Repositories Kolibri OS

Rev

Rev 1563 | Rev 2233 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
  4. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. $Revision: 2214 $
  10.  
  11. ;==============================================================================
  12. ;///// public functions ///////////////////////////////////////////////////////
  13. ;==============================================================================
  14.  
  15. window.BORDER_SIZE = 5
  16.  
  17. macro FuncTable name, table_name, [label]
  18. {
  19.   common
  20.     align 4
  21.     \label name#.#table_name dword
  22.   forward
  23.     dd name#.#label
  24.   common
  25.     name#.sizeof.#table_name = $ - name#.#table_name
  26. }
  27.  
  28. uglobal
  29.   common_colours rd 32
  30.   draw_limits    RECT
  31. endg
  32.  
  33. align 4
  34. ;------------------------------------------------------------------------------
  35. syscall_draw_window: ;///// system function 0 /////////////////////////////////
  36. ;------------------------------------------------------------------------------
  37. ;? <description>
  38. ;------------------------------------------------------------------------------
  39.         mov     eax, edx
  40.         shr     eax, 24
  41.         and     al, 0x0f
  42.         cmp     al, 5
  43.         jae     .exit
  44.  
  45.         push    eax
  46.         inc     [mouse_pause]
  47.         call    [_display.disable_mouse]
  48.         call    window._.sys_set_window
  49.         call    [_display.disable_mouse]
  50.         pop     eax
  51.  
  52.         or      al, al
  53.         jnz     @f
  54.  
  55.         ; type I - original style
  56.         call    drawwindow_I
  57.         jmp     window._.draw_window_caption.2
  58.  
  59.     @@: dec     al
  60.         jnz     @f
  61.  
  62.         ; type II - only reserve area, no draw
  63.         call    sys_window_mouse
  64.         dec     [mouse_pause]
  65.         call    [draw_pointer]
  66.         jmp     .exit
  67.  
  68.     @@: dec     al
  69.         jnz     @f
  70.  
  71.         ; type III  - new style
  72.         call    drawwindow_III
  73.         jmp     window._.draw_window_caption.2
  74.  
  75.         ; type IV & V - skinned window (resizable & not)
  76.     @@: mov     eax, [TASK_COUNT]
  77.         movzx   eax, word[WIN_POS + eax * 2]
  78.         cmp     eax, [CURRENT_TASK]
  79.         setz    al
  80.         movzx   eax, al
  81.         push    eax
  82.         call    drawwindow_IV
  83.         jmp     window._.draw_window_caption.2
  84.  
  85.   .exit:
  86.         ret
  87.  
  88. align 4
  89. ;------------------------------------------------------------------------------
  90. syscall_display_settings: ;///// system function 48 ///////////////////////////
  91. ;------------------------------------------------------------------------------
  92. ;; Redraw screen:
  93. ;< ebx = 0
  94. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  95. ;; Set button style:
  96. ;< ebx = 1
  97. ;< ecx = 0 (flat) or 1 (with gradient)
  98. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  99. ;; Set system color palette:
  100. ;< ebx = 2
  101. ;< ecx = pointer to color table
  102. ;< edx = size of color table
  103. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  104. ;; Get system color palette:
  105. ;< ebx = 3
  106. ;< ecx = pointer to color table buffer
  107. ;< edx = size of color table buffer
  108. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  109. ;; Get skinned caption height:
  110. ;< ebx = 4
  111. ;> eax = height in pixels
  112. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  113. ;; Get screen working area:
  114. ;< ebx = 5
  115. ;> eax = pack[16(left), 16(right)]
  116. ;> ebx = pack[16(top), 16(bottom)]
  117. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  118. ;; Set screen working area:
  119. ;< ebx = 6
  120. ;< ecx = pack[16(left), 16(right)]
  121. ;< edx = pack[16(top), 16(bottom)]
  122. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  123. ;; Get skin margins:
  124. ;< ebx = 7
  125. ;> eax = pack[16(left), 16(right)]
  126. ;> ebx = pack[16(top), 16(bottom)]
  127. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  128. ;; Set skin:
  129. ;< ebx = 8
  130. ;< ecx = pointer to FileInfoBlock struct
  131. ;> eax = FS error code
  132. ;------------------------------------------------------------------------------
  133.         cmp     ebx, .sizeof.ftable / 4
  134.         ja      @f
  135.         jmp     [.ftable + ebx * 4]
  136.     @@: ret
  137.  
  138.  
  139. align 4
  140. syscall_display_settings.00:
  141.         xor     eax, eax
  142.         inc     ebx
  143.         cmp     [windowtypechanged], ebx
  144.         jne     .exit
  145.         mov     [windowtypechanged], eax
  146.  
  147.         jmp     syscall_display_settings._.redraw_whole_screen
  148.  
  149.   .exit:
  150.         ret
  151.  
  152. align 4
  153. syscall_display_settings.01:
  154.         and     ecx, 1
  155.         cmp     ecx, [buttontype]
  156.         je      .exit
  157.         mov     [buttontype], ecx
  158.         mov     [windowtypechanged], ebx
  159.  
  160.   .exit:
  161.         ret
  162.  
  163. align 4
  164. syscall_display_settings.02:
  165.         dec     ebx
  166.         mov     esi, ecx
  167.         and     edx, 127
  168.         mov     edi, common_colours
  169.         mov     ecx, edx
  170.         rep     movsb
  171.         mov     [windowtypechanged], ebx
  172.         ret
  173.  
  174. align 4
  175. syscall_display_settings.03:
  176.         mov     edi, ecx
  177.         and     edx, 127
  178.         mov     esi, common_colours
  179.         mov     ecx, edx
  180.         rep     movsb
  181.         ret
  182.  
  183. align 4
  184. syscall_display_settings.04:
  185.         mov     eax, [_skinh]
  186.         mov     [esp + 32], eax
  187.         ret
  188.  
  189. align 4
  190. syscall_display_settings.05:
  191.         mov     eax, [screen_workarea.left - 2]
  192.         mov     ax, word[screen_workarea.right]
  193.         mov     [esp + 32], eax
  194.         mov     eax, [screen_workarea.top - 2]
  195.         mov     ax, word[screen_workarea.bottom]
  196.         mov     [esp + 20], eax
  197.         ret
  198.  
  199. align 4
  200. syscall_display_settings.06:
  201.         xor     esi, esi
  202.  
  203.         mov     edi, [Screen_Max_X]
  204.         mov     eax, ecx
  205.         movsx   ebx, ax
  206.         sar     eax, 16
  207.         cmp     eax, ebx
  208.         jge     .check_horizontal
  209.         inc     esi
  210.         or      eax, eax
  211.         jge     @f
  212.         xor     eax, eax
  213.     @@: mov     [screen_workarea.left], eax
  214.         cmp     ebx, edi
  215.         jle     @f
  216.         mov     ebx, edi
  217.     @@: mov     [screen_workarea.right], ebx
  218.  
  219.   .check_horizontal:
  220.         mov     edi, [Screen_Max_Y]
  221.         mov     eax, edx
  222.         movsx   ebx, ax
  223.         sar     eax, 16
  224.         cmp     eax, ebx
  225.         jge     .check_if_redraw_needed
  226.         inc     esi
  227.         or      eax, eax
  228.         jge     @f
  229.         xor     eax, eax
  230.     @@: mov     [screen_workarea.top], eax
  231.         cmp     ebx, edi
  232.         jle     @f
  233.         mov     ebx, edi
  234.     @@: mov     [screen_workarea.bottom], ebx
  235.  
  236.   .check_if_redraw_needed:
  237.         or      esi, esi
  238.         jz      .exit
  239.  
  240.         call    repos_windows
  241.         jmp     syscall_display_settings._.calculate_whole_screen
  242.  
  243.   .exit:
  244.         ret
  245.  
  246. align 4
  247. syscall_display_settings.07:
  248.         mov     eax, [_skinmargins + 0]
  249.         mov     [esp + 32], eax
  250.         mov     eax, [_skinmargins + 4]
  251.         mov     [esp + 20], eax
  252.         ret
  253.  
  254. align 4
  255. syscall_display_settings.08:
  256.         mov     ebx, ecx
  257.         call    read_skin_file
  258.         mov     [esp + 32], eax
  259.         test    eax, eax
  260.         jnz     .exit
  261.  
  262.         call    syscall_display_settings._.calculate_whole_screen
  263.         jmp     syscall_display_settings._.redraw_whole_screen
  264.  
  265.   .exit:
  266.         ret
  267.  
  268. syscall_display_settings._.calculate_whole_screen:
  269.         xor     eax, eax
  270.         xor     ebx, ebx
  271.         mov     ecx, [Screen_Max_X]
  272.         mov     edx, [Screen_Max_Y]
  273.         jmp     calculatescreen
  274.  
  275. syscall_display_settings._.redraw_whole_screen:
  276.         xor     eax, eax
  277.         mov     [draw_limits.left], eax
  278.         mov     [draw_limits.top], eax
  279.         mov     eax, [Screen_Max_X]
  280.         mov     [draw_limits.right], eax
  281.         mov     eax, [Screen_Max_Y]
  282.         mov     [draw_limits.bottom], eax
  283.         mov     eax, window_data
  284.         jmp     redrawscreen
  285.  
  286. align 4
  287. ;------------------------------------------------------------------------------
  288. syscall_set_window_shape: ;///// system function 50 ///////////////////////////
  289. ;------------------------------------------------------------------------------
  290. ;; Set window shape address:
  291. ;> ebx = 0
  292. ;> ecx = shape data address
  293. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  294. ;; Set window shape scale:
  295. ;> ebx = 1
  296. ;> ecx = scale power (resulting scale is 2^ebx)
  297. ;------------------------------------------------------------------------------
  298.         mov     edi, [current_slot]
  299.  
  300.         test    ebx, ebx
  301.         jne     .shape_scale
  302.         mov     [edi + APPDATA.wnd_shape], ecx
  303.  
  304.   .shape_scale:
  305.         dec     ebx
  306.         jnz     .exit
  307.         mov     [edi + APPDATA.wnd_shape_scale], ecx
  308.  
  309.   .exit:
  310.         ret
  311.  
  312. align 4
  313. ;------------------------------------------------------------------------------
  314. syscall_move_window: ;///// system function 67 ////////////////////////////////
  315. ;------------------------------------------------------------------------------
  316. ;? <description>
  317. ;------------------------------------------------------------------------------
  318.         mov     edi, [CURRENT_TASK]
  319.         shl     edi, 5
  320.         add     edi, window_data
  321.  
  322.         test    [edi + WDATA.fl_wdrawn], 1
  323.         jz      .exit
  324.  
  325.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  326.         jnz     .exit
  327.  
  328.         cmp     ebx, -1
  329.         jne     @f
  330.         mov     ebx, [edi + WDATA.box.left]
  331.     @@: cmp     ecx, -1
  332.         jne     @f
  333.         mov     ecx, [edi + WDATA.box.top]
  334.     @@: cmp     edx, -1
  335.         jne     @f
  336.         mov     edx, [edi + WDATA.box.width]
  337.     @@: cmp     esi, -1
  338.         jne     @f
  339.         mov     esi, [edi + WDATA.box.height]
  340.  
  341.     @@: push    esi edx ecx ebx
  342.         mov     eax, esp
  343.         mov     bl, [edi + WDATA.fl_wstate]
  344.         call    window._.set_window_box
  345.         add     esp, BOX.sizeof
  346.  
  347.         ; NOTE: do we really need this? to be reworked
  348. ;       mov     byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
  349. ;       mov     byte[MOUSE_BACKGROUND], 0 ; no mouse under
  350. ;       mov     byte[MOUSE_DOWN], 0 ; react to mouse up/down
  351.  
  352.         ; NOTE: do we really need this? to be reworked
  353. ;       call    [draw_pointer]
  354.  
  355.   .exit:
  356.         ret
  357.  
  358. align 4
  359. ;------------------------------------------------------------------------------
  360. syscall_window_settings: ;///// system function 71 /////////////////////////////
  361. ;------------------------------------------------------------------------------
  362. ;? <description>
  363. ;------------------------------------------------------------------------------
  364.         dec     ebx     ; subfunction #1 - set window caption
  365.         jnz     .exit_fail
  366.  
  367.         ; NOTE: only window owner thread can set its caption,
  368.         ;       so there's no parameter for PID/TID
  369.  
  370.         mov     edi, [CURRENT_TASK]
  371.         shl     edi, 5
  372.  
  373.         mov     [edi * 8 + SLOT_BASE + APPDATA.wnd_caption], ecx
  374.         or      [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
  375.  
  376.         call    window._.draw_window_caption
  377.  
  378.         xor     eax, eax ; eax = 0 (success)
  379.         ret
  380.  
  381. ;  .get_window_caption:
  382. ;        dec     eax     ; subfunction #2 - get window caption
  383. ;        jnz     .exit_fail
  384.  
  385.         ; not implemented yet
  386.  
  387.   .exit_fail:
  388.         xor     eax, eax
  389.         inc     eax     ; eax = 1 (fail)
  390.         ret
  391.  
  392. align 4
  393. ;------------------------------------------------------------------------------
  394. set_window_defaults: ;/////////////////////////////////////////////////////////
  395. ;------------------------------------------------------------------------------
  396. ;? <description>
  397. ;------------------------------------------------------------------------------
  398.         mov     byte [window_data + 0x20 + WDATA.cl_titlebar + 3], 1 ; desktop is not movable
  399.         push    eax ecx
  400.         xor     eax, eax
  401.         mov     ecx, WIN_STACK
  402.     @@: inc     eax
  403.         add     ecx, 2
  404.         ; process no
  405.         mov     [ecx + 0x000], ax
  406.         ; positions in stack
  407.         mov     [ecx + 0x400], ax
  408.         cmp     ecx, WIN_POS - 2
  409.         jne     @b
  410.         pop     ecx eax
  411.         ret
  412.  
  413. align 4
  414. ;------------------------------------------------------------------------------
  415. calculatescreen: ;/////////////////////////////////////////////////////////////
  416. ;------------------------------------------------------------------------------
  417. ;? Scan all windows from bottom to top, calling `setscreen` for each one
  418. ;? intersecting given screen area
  419. ;------------------------------------------------------------------------------
  420. ;> eax = left
  421. ;> ebx = top
  422. ;> ecx = right
  423. ;> edx = bottom
  424. ;------------------------------------------------------------------------------
  425.         push    esi
  426.         pushfd
  427.         cli
  428.  
  429.         mov     esi, 1
  430.         call    window._.set_screen
  431.  
  432.         push    ebp
  433.  
  434.         mov     ebp, [TASK_COUNT]
  435.         cmp     ebp, 1
  436.         jbe     .exit
  437.  
  438.         push    edx ecx ebx eax
  439.  
  440.   .next_window:
  441.         movzx   edi, word[WIN_POS + esi * 2]
  442.         shl     edi, 5
  443.  
  444.         cmp     [CURRENT_TASK + edi + TASKDATA.state], TSTATE_FREE
  445.         je      .skip_window
  446.  
  447.         add     edi, window_data
  448.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  449.         jnz     .skip_window
  450.  
  451.         mov     eax, [edi + WDATA.box.left]
  452.         cmp     eax, [esp + RECT.right]
  453.         jg      .skip_window
  454.         mov     ebx, [edi + WDATA.box.top]
  455.         cmp     ebx, [esp + RECT.bottom]
  456.         jg      .skip_window
  457.         mov     ecx, [edi + WDATA.box.width]
  458.         add     ecx, eax
  459.         cmp     ecx, [esp + RECT.left]
  460.         jl      .skip_window
  461.         mov     edx, [edi + WDATA.box.height]
  462.         add     edx, ebx
  463.         cmp     edx, [esp + RECT.top]
  464.         jl      .skip_window
  465.  
  466.         cmp     eax, [esp + RECT.left]
  467.         jae     @f
  468.         mov     eax, [esp + RECT.left]
  469.     @@: cmp     ebx, [esp + RECT.top]
  470.         jae     @f
  471.         mov     ebx, [esp + RECT.top]
  472.     @@: cmp     ecx, [esp + RECT.right]
  473.         jbe     @f
  474.         mov     ecx, [esp + RECT.right]
  475.     @@: cmp     edx, [esp + RECT.bottom]
  476.         jbe     @f
  477.         mov     edx, [esp + RECT.bottom]
  478.  
  479.     @@: push    esi
  480.         movzx   esi, word[WIN_POS + esi * 2]
  481.         call    window._.set_screen
  482.         pop     esi
  483.  
  484.   .skip_window:
  485.         inc     esi
  486.         dec     ebp
  487.         jnz     .next_window
  488.  
  489.         pop     eax ebx ecx edx
  490.  
  491.   .exit:
  492.         pop     ebp
  493.         popfd
  494.         pop     esi
  495.         ret
  496.  
  497. align 4
  498. ;------------------------------------------------------------------------------
  499. repos_windows: ;///////////////////////////////////////////////////////////////
  500. ;------------------------------------------------------------------------------
  501. ;? <description>
  502. ;------------------------------------------------------------------------------
  503.         mov     ecx, [TASK_COUNT]
  504.         mov     edi, window_data + WDATA.sizeof * 2
  505.         call    force_redraw_background
  506.         dec     ecx
  507.         jle     .exit
  508.  
  509.   .next_window:
  510.         mov     [edi + WDATA.fl_redraw], 1
  511.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  512.         jnz     .fix_maximized
  513.  
  514.         mov     eax, [edi + WDATA.box.left]
  515.         add     eax, [edi + WDATA.box.width]
  516.         mov     ebx, [Screen_Max_X]
  517.         cmp     eax, ebx
  518.         jle     .fix_vertical
  519.         mov     eax, [edi + WDATA.box.width]
  520.         sub     eax, ebx
  521.         jle     @f
  522.         mov     [edi + WDATA.box.width], ebx
  523.     @@: sub     ebx, [edi + WDATA.box.width]
  524.         mov     [edi + WDATA.box.left], ebx
  525.  
  526.   .fix_vertical:
  527.         mov     eax, [edi + WDATA.box.top]
  528.         add     eax, [edi + WDATA.box.height]
  529.         mov     ebx, [Screen_Max_Y]
  530.         cmp     eax, ebx
  531.         jle     .fix_client_box
  532.         mov     eax, [edi + WDATA.box.height]
  533.         sub     eax, ebx
  534.         jle     @f
  535.         mov     [edi + WDATA.box.height], ebx
  536.     @@: sub     ebx, [edi + WDATA.box.height]
  537.         mov     [edi + WDATA.box.top], ebx
  538.         jmp     .fix_client_box
  539.  
  540.   .fix_maximized:
  541.         mov     eax, [screen_workarea.left]
  542.         mov     [edi + WDATA.box.left], eax
  543.         sub     eax, [screen_workarea.right]
  544.         neg     eax
  545.         mov     [edi + WDATA.box.width], eax
  546.         mov     eax, [screen_workarea.top]
  547.         mov     [edi + WDATA.box.top], eax
  548.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  549.         jnz     .fix_client_box
  550.         sub     eax, [screen_workarea.bottom]
  551.         neg     eax
  552.         mov     [edi + WDATA.box.height], eax
  553.  
  554.   .fix_client_box:
  555.         call    window._.set_window_clientbox
  556.  
  557.         add     edi, WDATA.sizeof
  558.         loop    .next_window
  559.  
  560.   .exit:
  561.         ret
  562.  
  563. align 4
  564. ;------------------------------------------------------------------------------
  565. sys_window_mouse: ;////////////////////////////////////////////////////////////
  566. ;------------------------------------------------------------------------------
  567. ;? <description>
  568. ;------------------------------------------------------------------------------
  569.         ; NOTE: commented out since doesn't provide necessary functionality
  570.         ;       anyway, to be reworked
  571. ;       push    eax
  572. ;
  573. ;       mov     eax, [timer_ticks]
  574. ;       cmp     [new_window_starting], eax
  575. ;       jb      .exit
  576. ;
  577. ;       mov     byte[MOUSE_BACKGROUND], 0
  578. ;       mov     byte[DONT_DRAW_MOUSE], 0
  579. ;
  580. ;       mov     [new_window_starting], eax
  581. ;
  582. ; .exit:
  583. ;       pop     eax
  584.         ret
  585.  
  586. align 4
  587. ;------------------------------------------------------------------------------
  588. draw_rectangle: ;//////////////////////////////////////////////////////////////
  589. ;------------------------------------------------------------------------------
  590. ;> eax = pack[16(left), 16(right)]
  591. ;> ebx = pack[16(top), 16(bottom)]
  592. ;> esi = color
  593. ;------------------------------------------------------------------------------
  594.         push    eax ebx ecx edi
  595.  
  596.         xor     edi, edi
  597.  
  598.   .flags_set:
  599.         push    ebx
  600.  
  601.         ; set line color
  602.         mov     ecx, esi
  603.  
  604.         ; draw top border
  605.         rol     ebx, 16
  606.         push    ebx
  607.         rol     ebx, 16
  608.         pop     bx
  609.         call    [draw_line]
  610.  
  611.         ; draw bottom border
  612.         mov     ebx, [esp - 2]
  613.         pop     bx
  614.         call    [draw_line]
  615.  
  616.         pop     ebx
  617.         add     ebx, 1 * 65536 - 1
  618.  
  619.         ; draw left border
  620.         rol     eax, 16
  621.         push    eax
  622.         rol     eax, 16
  623.         pop     ax
  624.         call    [draw_line]
  625.  
  626.         ; draw right border
  627.         mov     eax, [esp - 2]
  628.         pop     ax
  629.         call    [draw_line]
  630.  
  631.         pop     edi ecx ebx eax
  632.         ret
  633.  
  634.   .forced:
  635.         push    eax ebx ecx edi
  636.         xor     edi, edi
  637.         inc     edi
  638.         jmp     .flags_set
  639.  
  640. align 4
  641. ;------------------------------------------------------------------------------
  642. drawwindow_I_caption: ;////////////////////////////////////////////////////////
  643. ;------------------------------------------------------------------------------
  644. ;? <description>
  645. ;------------------------------------------------------------------------------
  646.         push    [edx + WDATA.cl_titlebar]
  647.         mov     esi, edx
  648.  
  649.         mov     edx, [esi + WDATA.box.top]
  650.         mov     eax, edx
  651.         lea     ebx, [edx + 21]
  652.         inc     edx
  653.         add     eax, [esi + WDATA.box.height]
  654.  
  655.         cmp     ebx, eax
  656.         jbe     @f
  657.         mov     ebx, eax
  658.     @@: push    ebx
  659.  
  660.         xor     edi, edi
  661.  
  662.   .next_line:
  663.         mov     ebx, edx
  664.         shl     ebx, 16
  665.         add     ebx, edx
  666.         mov     eax, [esi + WDATA.box.left]
  667.         inc     eax
  668.         shl     eax, 16
  669.         add     eax, [esi + WDATA.box.left]
  670.         add     eax, [esi + WDATA.box.width]
  671.         dec     eax
  672.         mov     ecx, [esi + WDATA.cl_titlebar]
  673.         test    ecx, 0x80000000
  674.         jz      @f
  675.         sub     ecx, 0x00040404
  676.         mov     [esi + WDATA.cl_titlebar], ecx
  677.     @@: and     ecx, 0x00ffffff
  678.         call    [draw_line]
  679.         inc     edx
  680.         cmp     edx, [esp]
  681.         jb      .next_line
  682.  
  683.         add     esp, 4
  684.         pop     [esi + WDATA.cl_titlebar]
  685.         ret
  686.  
  687. align 4
  688. ;------------------------------------------------------------------------------
  689. drawwindow_I: ;////////////////////////////////////////////////////////////////
  690. ;------------------------------------------------------------------------------
  691. ;? <description>
  692. ;------------------------------------------------------------------------------
  693.         pushad
  694.  
  695.         ; window border
  696.  
  697.         mov     eax, [edx + WDATA.box.left - 2]
  698.         mov     ax, word[edx + WDATA.box.left]
  699.         add     ax, word[edx + WDATA.box.width]
  700.         mov     ebx, [edx + WDATA.box.top - 2]
  701.         mov     bx, word[edx + WDATA.box.top]
  702.         add     bx, word[edx + WDATA.box.height]
  703.  
  704.         mov     esi, [edx + WDATA.cl_frames]
  705.         call    draw_rectangle
  706.  
  707.         ; window caption
  708.  
  709.         call    drawwindow_I_caption
  710.  
  711.         ; window client area
  712.  
  713.         ; do we need to draw it?
  714.         mov     edi, [esi + WDATA.cl_workarea]
  715.         test    edi, 0x40000000
  716.         jnz     .exit
  717.  
  718.         ; does client area have a positive size on screen?
  719.         mov     edx, [esi + WDATA.box.top]
  720.         add     edx, 21 + 5
  721.         mov     ebx, [esi + WDATA.box.top]
  722.         add     ebx, [esi + WDATA.box.height]
  723.         cmp     edx, ebx
  724.         jg      .exit
  725.  
  726.         ; okay, let's draw it
  727.         mov     eax, 1
  728.         mov     ebx, 21
  729.         mov     ecx, [esi + WDATA.box.width]
  730.         mov     edx, [esi + WDATA.box.height]
  731.         call    [drawbar]
  732.  
  733.   .exit:
  734.         popad
  735.         ret
  736.  
  737. align 4
  738. ;------------------------------------------------------------------------------
  739. drawwindow_III_caption: ;/////////////////////////////////////////////////////
  740. ;------------------------------------------------------------------------------
  741. ;? <description>
  742. ;------------------------------------------------------------------------------
  743.         mov     ecx, [edx + WDATA.cl_titlebar]
  744.         push    ecx
  745.         mov     esi, edx
  746.         mov     edx, [esi + WDATA.box.top]
  747.         add     edx, 4
  748.         mov     ebx, [esi + WDATA.box.top]
  749.         add     ebx, 20
  750.         mov     eax, [esi + WDATA.box.top]
  751.         add     eax, [esi + WDATA.box.height]
  752.  
  753.         cmp     ebx, eax
  754.         jb      @f
  755.         mov     ebx, eax
  756.     @@: push    ebx
  757.  
  758.         xor     edi, edi
  759.  
  760.   .next_line:
  761.         mov     ebx, edx
  762.         shl     ebx, 16
  763.         add     ebx, edx
  764.         mov     eax, [esi + WDATA.box.left]
  765.         shl     eax, 16
  766.         add     eax, [esi + WDATA.box.left]
  767.         add     eax, [esi + WDATA.box.width]
  768.         add     eax, 4 * 65536 - 4
  769.         mov     ecx, [esi + WDATA.cl_titlebar]
  770.         test    ecx, 0x40000000
  771.         jz      @f
  772.         add     ecx, 0x00040404
  773.     @@: test    ecx, 0x80000000
  774.         jz      @f
  775.         sub     ecx, 0x00040404
  776.     @@: mov     [esi + WDATA.cl_titlebar], ecx
  777.         and     ecx, 0x00ffffff
  778.         call    [draw_line]
  779.         inc     edx
  780.         cmp     edx, [esp]
  781.         jb      .next_line
  782.  
  783.         add     esp, 4
  784.         pop     [esi + WDATA.cl_titlebar]
  785.         ret
  786.  
  787. align 4
  788. ;------------------------------------------------------------------------------
  789. drawwindow_III: ;//////////////////////////////////////////////////////////////
  790. ;------------------------------------------------------------------------------
  791. ;? <description>
  792. ;------------------------------------------------------------------------------
  793.         pushad
  794.  
  795.         ; window border
  796.  
  797.         mov     eax, [edx + WDATA.box.left - 2]
  798.         mov     ax, word[edx + WDATA.box.left]
  799.         add     ax, word[edx + WDATA.box.width]
  800.         mov     ebx, [edx + WDATA.box.top - 2]
  801.         mov     bx, word[edx + WDATA.box.top]
  802.         add     bx, word[edx + WDATA.box.height]
  803.  
  804.         mov     esi, [edx + WDATA.cl_frames]
  805.         shr     esi, 1
  806.         and     esi, 0x007f7f7f
  807.         call    draw_rectangle
  808.  
  809.         push    esi
  810.         mov     ecx, 3
  811.         mov     esi, [edx + WDATA.cl_frames]
  812.  
  813.   .next_frame:
  814.         add     eax, 1 * 65536 - 1
  815.         add     ebx, 1 * 65536 - 1
  816.         call    draw_rectangle
  817.         dec     ecx
  818.         jnz     .next_frame
  819.  
  820.         pop     esi
  821.         add     eax, 1 * 65536 - 1
  822.         add     ebx, 1 * 65536 - 1
  823.         call    draw_rectangle
  824.  
  825.         ; window caption
  826.  
  827.         call    drawwindow_III_caption
  828.  
  829.         ; window client area
  830.  
  831.         ; do we need to draw it?
  832.         mov     edi, [esi + WDATA.cl_workarea]
  833.         test    edi, 0x40000000
  834.         jnz     .exit
  835.  
  836.         ; does client area have a positive size on screen?
  837.         mov     edx, [esi + WDATA.box.top]
  838.         add     edx, 21 + 5
  839.         mov     ebx, [esi + WDATA.box.top]
  840.         add     ebx, [esi + WDATA.box.height]
  841.         cmp     edx, ebx
  842.         jg      .exit
  843.  
  844.         ; okay, let's draw it
  845.         mov     eax, 5
  846.         mov     ebx, 20
  847.         mov     ecx, [esi + WDATA.box.width]
  848.         mov     edx, [esi + WDATA.box.height]
  849.         sub     ecx, 4
  850.         sub     edx, 4
  851.         call    [drawbar]
  852.  
  853.   .exit:
  854.         popad
  855.         ret
  856.  
  857. align 4
  858. ;------------------------------------------------------------------------------
  859. waredraw: ;////////////////////////////////////////////////////////////////////
  860. ;------------------------------------------------------------------------------
  861. ;? Activate window, redrawing if necessary
  862. ;------------------------------------------------------------------------------
  863.         push    -1
  864.         mov     eax, [TASK_COUNT]
  865.         lea     eax, [WIN_POS + eax * 2]
  866.         cmp     eax, esi
  867.         pop     eax
  868.         je      .exit
  869.  
  870.         ; is it overlapped by another window now?
  871.         push    ecx
  872.         call    window._.check_window_draw
  873.         test    ecx, ecx
  874.         pop     ecx
  875.         jz      .do_not_draw
  876.  
  877.         ; yes it is, activate and update screen buffer
  878.         mov     byte[MOUSE_DOWN], 1
  879.         call    window._.window_activate
  880.  
  881.         pushad
  882.         mov     edi, [TASK_COUNT]
  883.         movzx   esi, word[WIN_POS + edi * 2]
  884.         shl     esi, 5
  885.         add     esi, window_data
  886.  
  887.         mov     eax, [esi + WDATA.box.left]
  888.         mov     ebx, [esi + WDATA.box.top]
  889.         mov     ecx, [esi + WDATA.box.width]
  890.         mov     edx, [esi + WDATA.box.height]
  891.  
  892.         add     ecx, eax
  893.         add     edx, ebx
  894.  
  895.         mov     edi, [TASK_COUNT]
  896.         movzx   esi, word[WIN_POS + edi * 2]
  897.         call    window._.set_screen
  898.         popad
  899.  
  900.         ; tell application to redraw itself
  901.         mov     [edi + WDATA.fl_redraw], 1
  902.         xor     eax, eax
  903.         jmp     .exit
  904.  
  905.   .do_not_draw:
  906.         ; no it's not, just activate the window
  907.         call    window._.window_activate
  908.         xor     eax, eax
  909.         mov     byte[MOUSE_BACKGROUND], al
  910.         mov     byte[DONT_DRAW_MOUSE], al
  911.  
  912.  
  913.   .exit:
  914.         mov     byte[MOUSE_DOWN], 0
  915.         inc     eax
  916.         ret
  917.  
  918. align 4
  919. ;------------------------------------------------------------------------------
  920. minimize_window: ;/////////////////////////////////////////////////////////////
  921. ;------------------------------------------------------------------------------
  922. ;> eax = window number on screen
  923. ;------------------------------------------------------------------------------
  924. ;# corrupts [dl*]
  925. ;------------------------------------------------------------------------------
  926.         push    edi
  927.         pushfd
  928.         cli
  929.  
  930.         ; is it already minimized?
  931.         movzx   edi, word[WIN_POS + eax * 2]
  932.         shl     edi, 5
  933.         add     edi, window_data
  934.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  935.         jnz     .exit
  936.  
  937.         push    eax ebx ecx edx esi
  938.  
  939.         ; no it's not, let's do that
  940.         or      [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  941.         mov     eax, [edi + WDATA.box.left]
  942.         mov     [draw_limits.left], eax
  943.         mov     ecx, eax
  944.         add     ecx, [edi + WDATA.box.width]
  945.         mov     [draw_limits.right], ecx
  946.         mov     ebx, [edi + WDATA.box.top]
  947.         mov     [draw_limits.top], ebx
  948.         mov     edx, ebx
  949.         add     edx, [edi + WDATA.box.height]
  950.         mov     [draw_limits.bottom], edx
  951.         call    calculatescreen
  952.         xor     esi, esi
  953.         xor     eax, eax
  954.         call    redrawscreen
  955.  
  956.         pop     esi edx ecx ebx eax
  957.  
  958.   .exit:
  959.         popfd
  960.         pop     edi
  961.         ret
  962.  
  963. align 4
  964. ;------------------------------------------------------------------------------
  965. restore_minimized_window: ;////////////////////////////////////////////////////
  966. ;------------------------------------------------------------------------------
  967. ;> eax = window number on screen
  968. ;------------------------------------------------------------------------------
  969. ;# corrupts [dl*]
  970. ;------------------------------------------------------------------------------
  971.         pushad
  972.         pushfd
  973.         cli
  974.  
  975.         ; is it already restored?
  976.         movzx   esi, word[WIN_POS + eax * 2]
  977.         mov     edi, esi
  978.         shl     edi, 5
  979.         add     edi, window_data
  980.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  981.         jz      .exit
  982.  
  983.         ; no it's not, let's do that
  984.         mov     [edi + WDATA.fl_redraw], 1
  985.         and     [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
  986.         mov     ebp, window._.set_screen
  987.         cmp     eax, [TASK_COUNT]
  988.         jz      @f
  989.         mov     ebp, calculatescreen
  990.     @@: mov     eax, [edi + WDATA.box.left]
  991.         mov     ebx, [edi + WDATA.box.top]
  992.         mov     ecx, [edi + WDATA.box.width]
  993.         mov     edx, [edi + WDATA.box.height]
  994.         add     ecx, eax
  995.         add     edx, ebx
  996.         call    ebp
  997.  
  998.         mov     byte[MOUSE_BACKGROUND], 0
  999.  
  1000.   .exit:
  1001.         popfd
  1002.         popad
  1003.         ret
  1004.  
  1005. align 4
  1006. ; TODO: remove this proc
  1007. ;------------------------------------------------------------------------------
  1008. window_check_events: ;/////////////////////////////////////////////////////////
  1009. ;------------------------------------------------------------------------------
  1010. ;? <description>
  1011. ;------------------------------------------------------------------------------
  1012.         ; do we have window minimize/restore request?
  1013.         cmp     [window_minimize], 0
  1014.         je      .exit
  1015.  
  1016.         ; okay, minimize or restore top-most window and exit
  1017.         mov     eax, [TASK_COUNT]
  1018.         mov     bl, 0
  1019.         xchg    [window_minimize], bl
  1020.         dec     bl
  1021.         jnz     @f
  1022.         call    minimize_window
  1023.         jmp     .exit
  1024.  
  1025.     @@: call    restore_minimized_window
  1026.  
  1027.   .exit:
  1028.         ret
  1029.  
  1030. align 4
  1031. ;------------------------------------------------------------------------------
  1032. sys_window_maximize_handler: ;/////////////////////////////////////////////////
  1033. ;------------------------------------------------------------------------------
  1034. ;? <description>
  1035. ;------------------------------------------------------------------------------
  1036. ;> esi = process slot
  1037. ;------------------------------------------------------------------------------
  1038.         mov     edi, esi
  1039.         shl     edi, 5
  1040.         add     edi, window_data
  1041.  
  1042.         ; can window change its height?
  1043.         ; only types 2 and 3 can be resized
  1044.         mov     dl, [edi + WDATA.fl_wstyle]
  1045.         test    dl, 2
  1046.         jz      .exit
  1047.  
  1048.         ; toggle normal/maximized window state
  1049.         mov     bl, [edi + WDATA.fl_wstate]
  1050.         xor     bl, WSTATE_MAXIMIZED
  1051.  
  1052.         ; calculate and set appropriate window bounds
  1053.         test    bl, WSTATE_MAXIMIZED
  1054.         jz      .restore_size
  1055.  
  1056.         mov     eax, [screen_workarea.left]
  1057.         mov     ecx, [screen_workarea.top]
  1058.         push    [screen_workarea.bottom] \
  1059.                 [screen_workarea.right] \
  1060.                 ecx \
  1061.                 eax
  1062.         sub     [esp + BOX.width], eax
  1063.         sub     [esp + BOX.height], ecx
  1064.         mov     eax, esp
  1065.         jmp     .set_box
  1066.  
  1067.   .restore_size:
  1068.         mov     eax, esi
  1069.         shl     eax, 8
  1070.         add     eax, SLOT_BASE + APPDATA.saved_box
  1071.         push    [eax + BOX.height] \
  1072.                 [eax + BOX.width] \
  1073.                 [eax + BOX.top] \
  1074.                 [eax + BOX.left]
  1075.         mov     eax, esp
  1076.  
  1077.   .set_box:
  1078.         test    bl, WSTATE_ROLLEDUP
  1079.         jz      @f
  1080.  
  1081.         xchg    eax, ecx
  1082.         call    window._.get_rolledup_height
  1083.         mov     [ecx + BOX.height], eax
  1084.         xchg    eax, ecx
  1085.  
  1086.     @@: call    window._.set_window_box
  1087.         add     esp, BOX.sizeof
  1088.  
  1089.   .exit:
  1090.         ret
  1091.  
  1092. align 4
  1093. ;------------------------------------------------------------------------------
  1094. sys_window_rollup_handler: ;///////////////////////////////////////////////////
  1095. ;------------------------------------------------------------------------------
  1096. ;? <description>
  1097. ;------------------------------------------------------------------------------
  1098. ;> esi = process slot
  1099. ;------------------------------------------------------------------------------
  1100.         mov     edx, esi
  1101.         shl     edx, 8
  1102.         add     edx, SLOT_BASE
  1103.  
  1104.         ; toggle normal/rolled up window state
  1105.         mov     bl, [edi + WDATA.fl_wstate]
  1106.         xor     bl, WSTATE_ROLLEDUP
  1107.  
  1108.         ; calculate and set appropriate window bounds
  1109.         test    bl, WSTATE_ROLLEDUP
  1110.         jz      .restore_size
  1111.  
  1112.         call    window._.get_rolledup_height
  1113.         push    eax \
  1114.                 [edi + WDATA.box.width] \
  1115.                 [edi + WDATA.box.top] \
  1116.                 [edi + WDATA.box.left]
  1117.         mov     eax, esp
  1118.         jmp     .set_box
  1119.  
  1120.   .restore_size:
  1121.         test    bl, WSTATE_MAXIMIZED
  1122.         jnz     @f
  1123.         add     esp, -BOX.sizeof
  1124.         lea     eax, [edx + APPDATA.saved_box]
  1125.         jmp     .set_box
  1126.  
  1127.     @@: mov     eax, [screen_workarea.top]
  1128.         push    [screen_workarea.bottom] \
  1129.                 [edi + WDATA.box.width] \
  1130.                 eax \
  1131.                 [edi + WDATA.box.left]
  1132.         sub     [esp + BOX.height], eax
  1133.         mov     eax, esp
  1134.  
  1135.   .set_box:
  1136.         call    window._.set_window_box
  1137.         add     esp, BOX.sizeof
  1138.  
  1139.         ret
  1140.  
  1141. align 4
  1142. ;------------------------------------------------------------------------------
  1143. sys_window_start_moving_handler: ;/////////////////////////////////////////////
  1144. ;------------------------------------------------------------------------------
  1145. ;? <description>
  1146. ;------------------------------------------------------------------------------
  1147. ;> eax = old (original) window box
  1148. ;> esi = process slot
  1149. ;------------------------------------------------------------------------------
  1150.         mov     edi, eax
  1151.         call    window._.draw_negative_box
  1152.  
  1153.         ret
  1154.  
  1155. align 4
  1156. ;------------------------------------------------------------------------------
  1157. sys_window_end_moving_handler: ;///////////////////////////////////////////////
  1158. ;------------------------------------------------------------------------------
  1159. ;? <description>
  1160. ;------------------------------------------------------------------------------
  1161. ;> eax = old (original) window box
  1162. ;> ebx = new (final) window box
  1163. ;> esi = process slot
  1164. ;------------------------------------------------------------------------------
  1165.         mov     edi, ebx
  1166.         call    window._.draw_negative_box
  1167.  
  1168.         mov     edi, esi
  1169.         shl     edi, 5
  1170.         add     edi, window_data
  1171.  
  1172.         mov     eax, ebx
  1173.         mov     bl, [edi + WDATA.fl_wstate]
  1174.         call    window._.set_window_box
  1175.         ret
  1176.  
  1177. align 4
  1178. ;------------------------------------------------------------------------------
  1179. sys_window_moving_handler: ;///////////////////////////////////////////////////
  1180. ;------------------------------------------------------------------------------
  1181. ;? <description>
  1182. ;------------------------------------------------------------------------------
  1183. ;> eax = old (from previous call) window box
  1184. ;> ebx = new (current) window box
  1185. ;> esi = process_slot
  1186. ;------------------------------------------------------------------------------
  1187.         mov     edi, eax
  1188.         call    window._.draw_negative_box
  1189.         mov     edi, ebx
  1190.         call    window._.draw_negative_box
  1191.         ret
  1192.  
  1193. ;==============================================================================
  1194. ;///// private functions //////////////////////////////////////////////////////
  1195. ;==============================================================================
  1196.  
  1197. iglobal
  1198.   FuncTable syscall_display_settings, ftable, \
  1199.     00, 01, 02, 03, 04, 05, 06, 07, 08
  1200.  
  1201.   align 4
  1202.   window_topleft dd \
  1203.     1, 21, \ ;type 0
  1204.     0,  0, \ ;type 1
  1205.     5, 20, \ ;type 2
  1206.     5,  ?, \ ;type 3 {set by skin}
  1207.     5,  ?    ;type 4 {set by skin}
  1208. endg
  1209.  
  1210. ;uglobal
  1211.   ; NOTE: commented out since doesn't provide necessary functionality anyway,
  1212.   ;       to be reworked
  1213. ; new_window_starting       dd ?
  1214. ;endg
  1215.  
  1216. align 4
  1217. ;------------------------------------------------------------------------------
  1218. window._.invalidate_screen: ;//////////////////////////////////////////////////
  1219. ;------------------------------------------------------------------------------
  1220. ;? <description>
  1221. ;------------------------------------------------------------------------------
  1222. ;> eax = old (original) window box
  1223. ;> ebx = new (final) window box
  1224. ;> edi = pointer to WDATA struct
  1225. ;------------------------------------------------------------------------------
  1226.         push    eax ebx
  1227.  
  1228.         ; TODO: do we really need `draw_limits`?
  1229.         ; Yes, they are used by background drawing code.
  1230.         mov     ecx, [eax + BOX.left]
  1231.         mov     edx, [ebx + BOX.left]
  1232.         cmp     ecx, edx
  1233.         jle     @f
  1234.         mov     ecx, edx
  1235.     @@: mov     [draw_limits.left], ecx
  1236.         mov     ecx, [eax + BOX.left]
  1237.         add     ecx, [eax + BOX.width]
  1238.         add     edx, [ebx + BOX.width]
  1239.         cmp     ecx, edx
  1240.         jae     @f
  1241.         mov     ecx, edx
  1242.     @@: mov     [draw_limits.right], ecx
  1243.         mov     ecx, [eax + BOX.top]
  1244.         mov     edx, [ebx + BOX.top]
  1245.         cmp     ecx, edx
  1246.         jle     @f
  1247.         mov     ecx, edx
  1248.     @@: mov     [draw_limits.top], ecx
  1249.         mov     ecx, [eax + BOX.top]
  1250.         add     ecx, [eax + BOX.height]
  1251.         add     edx, [ebx + BOX.height]
  1252.         cmp     ecx, edx
  1253.         jae     @f
  1254.         mov     ecx, edx
  1255.     @@: mov     [draw_limits.bottom], ecx
  1256.  
  1257.         ; recalculate screen buffer at old position
  1258.         push    ebx
  1259.         mov     edx, [eax + BOX.height]
  1260.         mov     ecx, [eax + BOX.width]
  1261.         mov     ebx, [eax + BOX.top]
  1262.         mov     eax, [eax + BOX.left]
  1263.         add     ecx, eax
  1264.         add     edx, ebx
  1265.         call    calculatescreen
  1266.         pop     eax
  1267.  
  1268.         ; recalculate screen buffer at new position
  1269.         mov     edx, [eax + BOX.height]
  1270.         mov     ecx, [eax + BOX.width]
  1271.         mov     ebx, [eax + BOX.top]
  1272.         mov     eax, [eax + BOX.left]
  1273.         add     ecx, eax
  1274.         add     edx, ebx
  1275.         call    calculatescreen
  1276.  
  1277.         mov     eax, edi
  1278.         call    redrawscreen
  1279.  
  1280.         ; tell window to redraw itself
  1281.         mov     [edi + WDATA.fl_redraw], 1
  1282.  
  1283.         pop     ebx eax
  1284.         ret
  1285.  
  1286. align 4
  1287. ;------------------------------------------------------------------------------
  1288. window._.set_window_box: ;/////////////////////////////////////////////////////
  1289. ;------------------------------------------------------------------------------
  1290. ;? <description>
  1291. ;------------------------------------------------------------------------------
  1292. ;> eax = pointer to BOX struct
  1293. ;> bl = new window state flags
  1294. ;> edi = pointer to WDATA struct
  1295. ;------------------------------------------------------------------------------
  1296.         push    eax ebx esi
  1297.  
  1298. ; don't do anything if the new box is identical to the old
  1299.         cmp     bl, [edi + WDATA.fl_wstate]
  1300.         jnz     @f
  1301.         mov     esi, eax
  1302.         push    edi
  1303. if WDATA.box
  1304.         add     edi, WDATA.box
  1305. end if
  1306.         mov     ecx, 4
  1307.         repz    cmpsd
  1308.         pop     edi
  1309.         jnz     @f
  1310.        
  1311.         mov     edi,eax
  1312.         mov     eax, [edi + BOX.left - 2]
  1313.         mov     ax, word[edi + BOX.left]
  1314.         add     ax, word[edi + BOX.width]
  1315.         mov     ebx, [edi + BOX.top - 2]
  1316.         mov     bx, word[edi + BOX.top]
  1317.         add     bx, word[edi + BOX.height]
  1318.         xor     esi,esi
  1319.         call    draw_rectangle.forced
  1320.         jmp     .exit
  1321. @@:
  1322.  
  1323.         add     esp, -BOX.sizeof
  1324.  
  1325.         mov     ebx, esp
  1326. if WDATA.box
  1327.         lea     esi, [edi + WDATA.box]
  1328. else
  1329.         mov     esi, edi ; optimization for WDATA.box = 0
  1330. end if
  1331.         xchg    eax, esi
  1332.         mov     ecx, BOX.sizeof
  1333.         call    memmove
  1334.         xchg    eax, esi
  1335.         xchg    ebx, esi
  1336.         call    memmove
  1337.         mov     eax, ebx
  1338.         mov     ebx, esi
  1339.  
  1340.         call    window._.check_window_position
  1341.         call    window._.set_window_clientbox
  1342.         call    window._.invalidate_screen
  1343.  
  1344.         add     esp, BOX.sizeof
  1345.  
  1346.         mov     cl, [esp + 4]
  1347.         mov     ch, cl
  1348.         xchg    cl, [edi + WDATA.fl_wstate]
  1349.  
  1350.         or      cl, ch
  1351.         test    cl, WSTATE_MAXIMIZED
  1352.         jnz     .exit
  1353.  
  1354.         mov     eax, edi
  1355.         sub     eax, window_data
  1356.         shl     eax, 3
  1357.         add     eax, SLOT_BASE
  1358.  
  1359.         lea     ebx, [edi + WDATA.box]
  1360.         xchg    esp, ebx
  1361.  
  1362.         pop     [eax + APPDATA.saved_box.left] \
  1363.                 [eax + APPDATA.saved_box.top] \
  1364.                 [eax + APPDATA.saved_box.width] \
  1365.                 edx
  1366.  
  1367.         xchg    esp, ebx
  1368.  
  1369.         test    ch, WSTATE_ROLLEDUP
  1370.         jnz     .exit
  1371.  
  1372.         mov     [eax + APPDATA.saved_box.height], edx
  1373.  
  1374.   .exit:
  1375.         pop     esi ebx eax
  1376.         ret
  1377.  
  1378. align 4
  1379. ;------------------------------------------------------------------------------
  1380. window._.set_window_clientbox: ;///////////////////////////////////////////////
  1381. ;------------------------------------------------------------------------------
  1382. ;? <description>
  1383. ;------------------------------------------------------------------------------
  1384. ;> edi = pointer to WDATA struct
  1385. ;------------------------------------------------------------------------------
  1386.         push    eax ecx edi
  1387.  
  1388.         mov     eax, [_skinh]
  1389.         mov     [window_topleft + 8 * 3 + 4], eax
  1390.         mov     [window_topleft + 8 * 4 + 4], eax
  1391.  
  1392.         mov     ecx, edi
  1393.         sub     edi, window_data
  1394.         shl     edi, 3
  1395.         test    [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE
  1396.         jz      .whole_window
  1397.  
  1398.         movzx   eax, [ecx + WDATA.fl_wstyle]
  1399.         and     eax, 0x0F
  1400.         mov     eax, [eax * 8 + window_topleft + 0]
  1401.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
  1402.         shl     eax, 1
  1403.         neg     eax
  1404.         add     eax, [ecx + WDATA.box.width]
  1405.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
  1406.  
  1407.         movzx   eax, [ecx + WDATA.fl_wstyle]
  1408.         and     eax, 0x0F
  1409.         push    [eax * 8 + window_topleft + 0]
  1410.         mov     eax, [eax * 8 + window_topleft + 4]
  1411.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
  1412.         neg     eax
  1413.         sub     eax, [esp]
  1414.         add     eax, [ecx + WDATA.box.height]
  1415.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
  1416.         add     esp, 4
  1417.         jmp     .exit
  1418.  
  1419.   .whole_window:
  1420.         xor     eax, eax
  1421.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
  1422.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
  1423.         mov     eax, [ecx + WDATA.box.width]
  1424.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
  1425.         mov     eax, [ecx + WDATA.box.height]
  1426.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
  1427.  
  1428.   .exit:
  1429.         pop     edi ecx eax
  1430.         ret
  1431.  
  1432. align 4
  1433. ;------------------------------------------------------------------------------
  1434. window._.sys_set_window: ;/////////////////////////////////////////////////////
  1435. ;------------------------------------------------------------------------------
  1436. ;? <description>
  1437. ;------------------------------------------------------------------------------
  1438. ;< edx = pointer to WDATA struct
  1439. ;------------------------------------------------------------------------------
  1440.         mov     eax, [CURRENT_TASK]
  1441.         shl     eax, 5
  1442.         add     eax, window_data
  1443.  
  1444.         ; save window colors
  1445.         mov     [eax + WDATA.cl_workarea], edx
  1446.         mov     [eax + WDATA.cl_titlebar], esi
  1447.         mov     [eax + WDATA.cl_frames], edi
  1448.  
  1449.         mov     edi, eax
  1450.  
  1451.         ; was it already defined before?
  1452.         test    [edi + WDATA.fl_wdrawn], 1
  1453.         jnz     .set_client_box
  1454.         or      [edi + WDATA.fl_wdrawn], 1
  1455.  
  1456.         ; NOTE: commented out since doesn't provide necessary functionality
  1457.         ;       anyway, to be reworked
  1458. ;       mov     eax, [timer_ticks] ; [0xfdf0]
  1459. ;       add     eax, 100
  1460. ;       mov     [new_window_starting], eax
  1461.  
  1462.         ; no it wasn't, performing initial window definition
  1463.         movzx   eax, bx
  1464.         mov     [edi + WDATA.box.width], eax
  1465.         movzx   eax, cx
  1466.         mov     [edi + WDATA.box.height], eax
  1467.         sar     ebx, 16
  1468.         sar     ecx, 16
  1469.         mov     [edi + WDATA.box.left], ebx
  1470.         mov     [edi + WDATA.box.top], ecx
  1471.  
  1472.         call    window._.check_window_position
  1473.  
  1474.         push    ecx edi
  1475.  
  1476.         mov     cl, [edi + WDATA.fl_wstyle]
  1477.         mov     eax, [edi + WDATA.cl_frames]
  1478.  
  1479.         sub     edi, window_data
  1480.         shl     edi, 3
  1481.         add     edi, SLOT_BASE
  1482.  
  1483.         and     cl, 0x0F
  1484.         cmp     cl, 3
  1485.         je      @f
  1486.         cmp     cl, 4
  1487.         je      @f
  1488.  
  1489.         xor     eax, eax
  1490.  
  1491.     @@: mov     [edi + APPDATA.wnd_caption], eax
  1492.  
  1493.         mov     esi, [esp]
  1494.         add     edi, APPDATA.saved_box
  1495.         movsd
  1496.         movsd
  1497.         movsd
  1498.         movsd
  1499.  
  1500.         pop     edi ecx
  1501.  
  1502.         mov     esi, [CURRENT_TASK]
  1503.         movzx   esi, word[WIN_STACK + esi * 2]
  1504.         lea     esi, [WIN_POS + esi * 2]
  1505.         call    waredraw
  1506.  
  1507.         mov     eax, [edi + WDATA.box.left]
  1508.         mov     ebx, [edi + WDATA.box.top]
  1509.         mov     ecx, [edi + WDATA.box.width]
  1510.         mov     edx, [edi + WDATA.box.height]
  1511.         add     ecx, eax
  1512.         add     edx, ebx
  1513.         call    calculatescreen
  1514.  
  1515.         mov     byte[KEY_COUNT], 0           ; empty keyboard buffer
  1516.         mov     byte[BTN_COUNT], 0           ; empty button buffer
  1517.  
  1518.   .set_client_box:
  1519.         ; update window client box coordinates
  1520.         call    window._.set_window_clientbox
  1521.  
  1522.         ; reset window redraw flag and exit
  1523.         mov     [edi + WDATA.fl_redraw], 0
  1524.         mov     edx, edi
  1525.         ret
  1526.  
  1527. align 4
  1528. ;------------------------------------------------------------------------------
  1529. window._.check_window_position: ;//////////////////////////////////////////////
  1530. ;------------------------------------------------------------------------------
  1531. ;? Check if window is inside screen area
  1532. ;------------------------------------------------------------------------------
  1533. ;> edi = pointer to WDATA
  1534. ;------------------------------------------------------------------------------
  1535.         push    eax ebx ecx edx esi
  1536.  
  1537.         mov     eax, [edi + WDATA.box.left]
  1538.         mov     ebx, [edi + WDATA.box.top]
  1539.         mov     ecx, [edi + WDATA.box.width]
  1540.         mov     edx, [edi + WDATA.box.height]
  1541.  
  1542.         mov     esi, [Screen_Max_X]
  1543.         cmp     ecx, esi
  1544.         ja      .fix_width_high
  1545.  
  1546.   .check_left:
  1547.         or      eax, eax
  1548.         jl      .fix_left_low
  1549.         add     eax, ecx
  1550.         cmp     eax, esi
  1551.         jg      .fix_left_high
  1552.  
  1553.   .check_height:
  1554.         mov     esi, [Screen_Max_Y]
  1555.         cmp     edx, esi
  1556.         ja      .fix_height_high
  1557.  
  1558.   .check_top:
  1559.         or      ebx, ebx
  1560.         jl      .fix_top_low
  1561.         add     ebx, edx
  1562.         cmp     ebx, esi
  1563.         jg      .fix_top_high
  1564.  
  1565.   .exit:
  1566.         pop     esi edx ecx ebx eax
  1567.         ret
  1568.  
  1569.   .fix_width_high:
  1570.         mov     ecx, esi
  1571.         mov     [edi + WDATA.box.width], esi
  1572.         jmp     .check_left
  1573.  
  1574.   .fix_left_low:
  1575.         xor     eax, eax
  1576.         mov     [edi + WDATA.box.left], eax
  1577.         jmp     .check_height
  1578.  
  1579.   .fix_left_high:
  1580.         mov     eax, esi
  1581.         sub     eax, ecx
  1582.         mov     [edi + WDATA.box.left], eax
  1583.         jmp     .check_height
  1584.  
  1585.   .fix_height_high:
  1586.         mov     edx, esi
  1587.         mov     [edi + WDATA.box.height], esi
  1588.         jmp     .check_top
  1589.  
  1590.   .fix_top_low:
  1591.         xor     ebx, ebx
  1592.         mov     [edi + WDATA.box.top], ebx
  1593.         jmp     .exit
  1594.  
  1595.   .fix_top_high:
  1596.         mov     ebx, esi
  1597.         sub     ebx, edx
  1598.         mov     [edi + WDATA.box.top], ebx
  1599.         jmp     .exit
  1600.  
  1601. align 4
  1602. ;------------------------------------------------------------------------------
  1603. window._.get_titlebar_height: ;////////////////////////////////////////////////
  1604. ;------------------------------------------------------------------------------
  1605. ;? <description>
  1606. ;------------------------------------------------------------------------------
  1607. ;> edi = pointer to WDATA
  1608. ;------------------------------------------------------------------------------
  1609.         mov     al, [edi + WDATA.fl_wstyle]
  1610.         and     al, 0x0f
  1611.         cmp     al, 0x03
  1612.         jne     @f
  1613.         mov     eax, [_skinh]
  1614.         ret
  1615.     @@: mov     eax, 21
  1616.         ret
  1617.  
  1618. align 4
  1619. ;------------------------------------------------------------------------------
  1620. window._.get_rolledup_height: ;////////////////////////////////////////////////
  1621. ;------------------------------------------------------------------------------
  1622. ;? <description>
  1623. ;------------------------------------------------------------------------------
  1624. ;> edi = pointer to WDATA
  1625. ;------------------------------------------------------------------------------
  1626.         mov     al, [edi + WDATA.fl_wstyle]
  1627.         and     al, 0x0f
  1628.         cmp     al, 0x03
  1629.         jb      @f
  1630.         mov     eax, [_skinh]
  1631.         add     eax, 3
  1632.         ret
  1633.     @@: or      al, al
  1634.         jnz     @f
  1635.         mov     eax, 21
  1636.         ret
  1637.     @@: mov     eax, 21 + 2
  1638.         ret
  1639.  
  1640. align 4
  1641. ;------------------------------------------------------------------------------
  1642. window._.set_screen: ;/////////////////////////////////////////////////////////
  1643. ;------------------------------------------------------------------------------
  1644. ;? Reserve window area in screen buffer
  1645. ;------------------------------------------------------------------------------
  1646. ;> eax = left
  1647. ;> ebx = top
  1648. ;> ecx = right
  1649. ;> edx = bottom
  1650. ;> esi = process number
  1651. ;------------------------------------------------------------------------------
  1652. virtual at esp
  1653.   ff_x     dd ?
  1654.   ff_y     dd ?
  1655.   ff_width dd ?
  1656.   ff_xsz   dd ?
  1657.   ff_ysz   dd ?
  1658.   ff_scale dd ?
  1659. end virtual
  1660.  
  1661.         pushad
  1662.  
  1663.         cmp     esi, 1
  1664.         jz      .check_for_shaped_window
  1665.         mov     edi, esi
  1666.         shl     edi, 5
  1667.         cmp     [window_data + edi + WDATA.box.width], 0
  1668.         jnz     .check_for_shaped_window
  1669.         cmp     [window_data + edi + WDATA.box.height], 0
  1670.         jz      .exit
  1671.  
  1672.   .check_for_shaped_window:
  1673.         mov     edi, esi
  1674.         shl     edi, 8
  1675.         add     edi, SLOT_BASE
  1676.         cmp     [edi + APPDATA.wnd_shape], 0
  1677.         jne     .shaped_window
  1678.  
  1679.         ; get x&y size
  1680.         sub     ecx, eax
  1681.         sub     edx, ebx
  1682.         inc     ecx
  1683.         inc     edx
  1684.  
  1685.         ; get WinMap start
  1686.         push    esi
  1687.         mov     edi, [Screen_Max_X]
  1688.         inc     edi
  1689.         mov     esi, edi
  1690.         imul    edi, ebx
  1691.         add     edi, eax
  1692.         add     edi, [_WinMapAddress]
  1693.         pop     eax
  1694.         mov     ah, al
  1695.         push    ax
  1696.         shl     eax, 16
  1697.         pop     ax
  1698.  
  1699.   .next_line:
  1700.         push    ecx
  1701.         shr     ecx, 2
  1702.         rep     stosd
  1703.         mov     ecx, [esp]
  1704.         and     ecx, 3
  1705.         rep     stosb
  1706.         pop     ecx
  1707.         add     edi, esi
  1708.         sub     edi, ecx
  1709.         dec     edx
  1710.         jnz     .next_line
  1711.  
  1712.         jmp     .exit
  1713.  
  1714.   .shaped_window:
  1715.         ;  for (y=0; y <= x_size; y++)
  1716.         ;      for (x=0; x <= x_size; x++)
  1717.         ;          if (shape[coord(x,y,scale)]==1)
  1718.         ;             set_pixel(x, y, process_number);
  1719.  
  1720.         sub     ecx, eax
  1721.         sub     edx, ebx
  1722.         inc     ecx
  1723.         inc     edx
  1724.  
  1725.         push    [edi + APPDATA.wnd_shape_scale]  ; push scale first -> for loop
  1726.  
  1727.         ; get WinMap start  -> ebp
  1728.         push    eax
  1729.         mov     eax, [Screen_Max_X] ; screen_sx
  1730.         inc     eax
  1731.         imul    eax, ebx
  1732.         add     eax, [esp]
  1733.         add     eax, [_WinMapAddress]
  1734.         mov     ebp, eax
  1735.  
  1736.         mov     edi, [edi + APPDATA.wnd_shape]
  1737.         pop     eax
  1738.  
  1739.         ; eax = x_start
  1740.         ; ebx = y_start
  1741.         ; ecx = x_size
  1742.         ; edx = y_size
  1743.         ; esi = process_number
  1744.         ; edi = &shape
  1745.         ;       [scale]
  1746.         push    edx ecx ; for loop - x,y size
  1747.  
  1748.         mov     ecx, esi
  1749.         shl     ecx, 5
  1750.         mov     edx, [window_data + ecx + WDATA.box.top]
  1751.         push    [window_data + ecx + WDATA.box.width]           ; for loop - width
  1752.         mov     ecx, [window_data + ecx + WDATA.box.left]
  1753.         sub     ebx, edx
  1754.         sub     eax, ecx
  1755.         push    ebx eax ; for loop - x,y
  1756.  
  1757.         add     [ff_xsz], eax
  1758.         add     [ff_ysz], ebx
  1759.  
  1760.         mov     ebx, [ff_y]
  1761.  
  1762.   .ff_new_y:
  1763.         mov     edx, [ff_x]
  1764.  
  1765.   .ff_new_x:
  1766.         ; -- body --
  1767.         mov     ecx, [ff_scale]
  1768.         mov     eax, [ff_width]
  1769.         inc     eax
  1770.         shr     eax, cl
  1771.         push    ebx edx
  1772.         shr     ebx, cl
  1773.         shr     edx, cl
  1774.         imul    eax, ebx
  1775.         add     eax, edx
  1776.         pop     edx ebx
  1777.         add     eax, edi
  1778.         call    .read_byte
  1779.         test    al,al
  1780.         jz      @f
  1781.         mov     eax, esi
  1782.         mov     [ebp], al
  1783.         ; -- end body --
  1784.     @@: inc     ebp
  1785.         inc     edx
  1786.         cmp     edx, [ff_xsz]
  1787.         jb      .ff_new_x
  1788.  
  1789.         sub     ebp, [ff_xsz]
  1790.         add     ebp, [ff_x]
  1791.         add     ebp, [Screen_Max_X]  ; screen.x
  1792.         inc     ebp
  1793.         inc     ebx
  1794.         cmp     ebx, [ff_ysz]
  1795.         jb      .ff_new_y
  1796.  
  1797.         add     esp, 24
  1798.  
  1799.   .exit:
  1800.         popad
  1801.         ret
  1802.  
  1803.   .read_byte:
  1804.         ; eax - address
  1805.         ; esi - slot
  1806.         push    eax ecx edx esi
  1807.         xchg    eax, esi
  1808.         lea     ecx, [esp + 12]
  1809.         mov     edx, 1
  1810.         call    read_process_memory
  1811.         pop     esi edx ecx eax
  1812.         ret
  1813.  
  1814. align 4
  1815. ;------------------------------------------------------------------------------
  1816. window._.window_activate: ;////////////////////////////////////////////////////
  1817. ;------------------------------------------------------------------------------
  1818. ;? Activate window
  1819. ;------------------------------------------------------------------------------
  1820. ;> esi = pointer to WIN_POS+ window data
  1821. ;------------------------------------------------------------------------------
  1822.         push    eax ebx
  1823.  
  1824.         ; if type of current active window is 3 or 4, it must be redrawn
  1825.         mov     ebx, [TASK_COUNT]
  1826.         movzx   ebx, word[WIN_POS + ebx * 2]
  1827.         shl     ebx, 5
  1828.         add     eax, window_data
  1829.         mov     al, [window_data + ebx + WDATA.fl_wstyle]
  1830.         and     al, 0x0f
  1831.         cmp     al, 0x03
  1832.         je      .set_window_redraw_flag
  1833.         cmp     al, 0x04
  1834.         jne     .move_others_down
  1835.  
  1836.   .set_window_redraw_flag:
  1837.         mov     [window_data + ebx + WDATA.fl_redraw], 1
  1838.  
  1839.   .move_others_down:
  1840.         ; ax <- process no
  1841.         movzx   ebx, word[esi]
  1842.         ; ax <- position in window stack
  1843.         movzx   ebx, word[WIN_STACK + ebx * 2]
  1844.  
  1845.         ; drop others
  1846.         xor     eax, eax
  1847.  
  1848.   .next_stack_window:
  1849.         cmp     eax, [TASK_COUNT]
  1850.         jae     .move_self_up
  1851.         inc     eax
  1852.         cmp     [WIN_STACK + eax * 2], bx
  1853.         jbe     .next_stack_window
  1854.         dec     word[WIN_STACK + eax * 2]
  1855.         jmp     .next_stack_window
  1856.  
  1857.   .move_self_up:
  1858.         movzx   ebx, word[esi]
  1859.         ; number of processes
  1860.         mov     ax, [TASK_COUNT]
  1861.         ; this is the last (and the upper)
  1862.         mov     [WIN_STACK + ebx * 2], ax
  1863.  
  1864.         ; update on screen - window stack
  1865.         xor     eax, eax
  1866.  
  1867.   .next_window_pos:
  1868.         cmp     eax, [TASK_COUNT]
  1869.         jae     .reset_vars
  1870.         inc     eax
  1871.         movzx   ebx, word[WIN_STACK + eax * 2]
  1872.         mov     [WIN_POS + ebx * 2], ax
  1873.         jmp     .next_window_pos
  1874.  
  1875.   .reset_vars:
  1876.         mov     byte[KEY_COUNT], 0
  1877.         mov     byte[BTN_COUNT], 0
  1878.         mov     word[MOUSE_SCROLL_H], 0
  1879.         mov     word[MOUSE_SCROLL_V], 0
  1880.  
  1881.         pop     ebx eax
  1882.         ret
  1883.  
  1884. align 4
  1885. ;------------------------------------------------------------------------------
  1886. window._.check_window_draw: ;//////////////////////////////////////////////////
  1887. ;------------------------------------------------------------------------------
  1888. ;? Check if window is necessary to draw
  1889. ;------------------------------------------------------------------------------
  1890. ;> edi = pointer to WDATA
  1891. ;------------------------------------------------------------------------------
  1892.         mov     cl, [edi + WDATA.fl_wstyle]
  1893.         and     cl, 0x0f
  1894.         cmp     cl, 3
  1895.         je      .exit.redraw      ; window type 3
  1896.         cmp     cl, 4
  1897.         je      .exit.redraw      ; window type 4
  1898.  
  1899.         push    eax ebx edx esi
  1900.  
  1901.         mov     eax, edi
  1902.         sub     eax, window_data
  1903.         shr     eax, 5
  1904.  
  1905.         movzx   eax, word[WIN_STACK + eax * 2]  ; get value of the curr process
  1906.         lea     esi, [WIN_POS + eax * 2]        ; get address of this process at 0xC400
  1907.  
  1908.   .next_window:
  1909.         add     esi, 2
  1910.  
  1911.         mov     eax, [TASK_COUNT]
  1912.         lea     eax, word[WIN_POS + eax * 2] ; number of the upper window
  1913.  
  1914.         cmp     esi, eax
  1915.         ja      .exit.no_redraw
  1916.  
  1917.         movzx   edx, word[esi]
  1918.         shl     edx, 5
  1919.         cmp     [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
  1920.         je      .next_window
  1921.  
  1922.         mov     eax, [edi + WDATA.box.top]
  1923.         mov     ebx, [edi + WDATA.box.height]
  1924.         add     ebx, eax
  1925.  
  1926.         mov     ecx, [window_data + edx + WDATA.box.top]
  1927.         cmp     ecx, ebx
  1928.         jge     .next_window
  1929.         add     ecx, [window_data + edx + WDATA.box.height]
  1930.         cmp     eax, ecx
  1931.         jge     .next_window
  1932.  
  1933.         mov     eax, [edi + WDATA.box.left]
  1934.         mov     ebx, [edi + WDATA.box.width]
  1935.         add     ebx, eax
  1936.  
  1937.         mov     ecx, [window_data + edx + WDATA.box.left]
  1938.         cmp     ecx, ebx
  1939.         jge     .next_window
  1940.         add     ecx, [window_data + edx + WDATA.box.width]
  1941.         cmp     eax, ecx
  1942.         jge     .next_window
  1943.  
  1944.         pop     esi edx ebx eax
  1945.  
  1946.   .exit.redraw:
  1947.         xor     ecx, ecx
  1948.         inc     ecx
  1949.         ret
  1950.  
  1951.   .exit.no_redraw:
  1952.         pop     esi edx ebx eax
  1953.         xor     ecx, ecx
  1954.         ret
  1955.  
  1956. align 4
  1957. ;------------------------------------------------------------------------------
  1958. window._.draw_window_caption: ;////////////////////////////////////////////////
  1959. ;------------------------------------------------------------------------------
  1960. ;? <description>
  1961. ;------------------------------------------------------------------------------
  1962.         inc     [mouse_pause]
  1963.         call    [_display.disable_mouse]
  1964.  
  1965.         xor     eax, eax
  1966.         mov     edx, [TASK_COUNT]
  1967.         movzx   edx, word[WIN_POS + edx * 2]
  1968.         cmp     edx, [CURRENT_TASK]
  1969.         jne     @f
  1970.         inc     eax
  1971.     @@: mov     edx, [CURRENT_TASK]
  1972.         shl     edx, 5
  1973.         add     edx, window_data
  1974.         movzx   ebx, [edx + WDATA.fl_wstyle]
  1975.         and     bl, 0x0F
  1976.         cmp     bl, 3
  1977.         je      .draw_caption_style_3
  1978.         cmp     bl, 4
  1979.         je      .draw_caption_style_3
  1980.  
  1981.         jmp     .not_style_3
  1982.  
  1983.   .draw_caption_style_3:
  1984.         push    edx
  1985.         call    drawwindow_IV_caption
  1986.         add     esp, 4
  1987.         jmp     .2
  1988.  
  1989.   .not_style_3:
  1990.         cmp     bl, 2
  1991.         jne     .not_style_2
  1992.  
  1993.         call    drawwindow_III_caption
  1994.         jmp     .2
  1995.  
  1996.   .not_style_2:
  1997.         cmp     bl, 0
  1998.         jne     .2
  1999.  
  2000.         call    drawwindow_I_caption
  2001.  
  2002.   .2:   mov     edi, [CURRENT_TASK]
  2003.         shl     edi, 5
  2004.         test    [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
  2005.         jz      .exit
  2006.         mov     edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption]
  2007.         or      edx, edx
  2008.         jz      .exit
  2009.  
  2010.         movzx   eax, [edi + window_data + WDATA.fl_wstyle]
  2011.         and     al, 0x0F
  2012.         cmp     al, 3
  2013.         je      .skinned
  2014.         cmp     al, 4
  2015.         je      .skinned
  2016.  
  2017.         jmp     .not_skinned
  2018.  
  2019.   .skinned:
  2020.         mov     ebp, [edi + window_data + WDATA.box.left - 2]
  2021.         mov     bp, word[edi + window_data + WDATA.box.top]
  2022.         movzx   eax, word[edi + window_data + WDATA.box.width]
  2023.         sub     ax, [_skinmargins.left]
  2024.         sub     ax, [_skinmargins.right]
  2025.         push    edx
  2026.         cwde
  2027.         cdq
  2028.         mov     ebx, 6
  2029.         idiv    ebx
  2030.         pop     edx
  2031.         or      eax, eax
  2032.         js      .exit
  2033.  
  2034.         mov     esi, eax
  2035.         mov     ebx, dword[_skinmargins.left - 2]
  2036.         mov     bx, word[_skinh]
  2037.         sub     bx, [_skinmargins.bottom]
  2038.         sub     bx, [_skinmargins.top]
  2039.         sar     bx, 1
  2040.         adc     bx, 0
  2041.         add     bx, [_skinmargins.top]
  2042.         add     bx, -3
  2043.         add     ebx, ebp
  2044.         jmp     .dodraw
  2045.  
  2046.   .not_skinned:
  2047.         cmp     al, 1
  2048.         je      .exit
  2049.  
  2050.         mov     ebp, [edi + window_data + WDATA.box.left - 2]
  2051.         mov     bp, word[edi + window_data + WDATA.box.top]
  2052.         movzx   eax, word[edi + window_data + WDATA.box.width]
  2053.         sub     eax, 16
  2054.         push    edx
  2055.         cwde
  2056.         cdq
  2057.         mov     ebx, 6
  2058.         idiv    ebx
  2059.         pop     edx
  2060.         or      eax, eax
  2061.         js      .exit
  2062.  
  2063.         mov     esi, eax
  2064.         mov     ebx, 0x00080007
  2065.         add     ebx, ebp
  2066.  
  2067.   .dodraw:
  2068.         mov     ecx, [common_colours + 16]
  2069.         or      ecx, 0x80000000
  2070.         xor     edi, edi
  2071.         call    dtext_asciiz_esi
  2072.  
  2073.   .exit:
  2074.         dec     [mouse_pause]
  2075.         call    [draw_pointer]
  2076.         ret
  2077.  
  2078. align 4
  2079. ;------------------------------------------------------------------------------
  2080. window._.draw_negative_box: ;//////////////////////////////////////////////////
  2081. ;------------------------------------------------------------------------------
  2082. ;? Draw negative box
  2083. ;------------------------------------------------------------------------------
  2084. ;> edi = pointer to BOX struct
  2085. ;------------------------------------------------------------------------------
  2086.         push    eax ebx esi
  2087.         mov     eax, [edi + BOX.left - 2]
  2088.         mov     ax, word[edi + BOX.left]
  2089.         add     ax, word[edi + BOX.width]
  2090.         mov     ebx, [edi + BOX.top - 2]
  2091.         mov     bx, word[edi + BOX.top]
  2092.         add     bx, word[edi + BOX.height]
  2093.         mov     esi, 0x01000000
  2094.         call    draw_rectangle.forced
  2095.         pop     esi ebx eax
  2096.         ret
  2097.