Subversion Repositories Kolibri OS

Rev

Rev 1563 | Rev 2219 | 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: 1563 $
  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.         jz      .exit
  1310. @@:
  1311.  
  1312.         add     esp, -BOX.sizeof
  1313.  
  1314.         mov     ebx, esp
  1315. if WDATA.box
  1316.         lea     esi, [edi + WDATA.box]
  1317. else
  1318.         mov     esi, edi ; optimization for WDATA.box = 0
  1319. end if
  1320.         xchg    eax, esi
  1321.         mov     ecx, BOX.sizeof
  1322.         call    memmove
  1323.         xchg    eax, esi
  1324.         xchg    ebx, esi
  1325.         call    memmove
  1326.         mov     eax, ebx
  1327.         mov     ebx, esi
  1328.  
  1329.         call    window._.check_window_position
  1330.         call    window._.set_window_clientbox
  1331.         call    window._.invalidate_screen
  1332.  
  1333.         add     esp, BOX.sizeof
  1334.  
  1335.         mov     cl, [esp + 4]
  1336.         mov     ch, cl
  1337.         xchg    cl, [edi + WDATA.fl_wstate]
  1338.  
  1339.         or      cl, ch
  1340.         test    cl, WSTATE_MAXIMIZED
  1341.         jnz     .exit
  1342.  
  1343.         mov     eax, edi
  1344.         sub     eax, window_data
  1345.         shl     eax, 3
  1346.         add     eax, SLOT_BASE
  1347.  
  1348.         lea     ebx, [edi + WDATA.box]
  1349.         xchg    esp, ebx
  1350.  
  1351.         pop     [eax + APPDATA.saved_box.left] \
  1352.                 [eax + APPDATA.saved_box.top] \
  1353.                 [eax + APPDATA.saved_box.width] \
  1354.                 edx
  1355.  
  1356.         xchg    esp, ebx
  1357.  
  1358.         test    ch, WSTATE_ROLLEDUP
  1359.         jnz     .exit
  1360.  
  1361.         mov     [eax + APPDATA.saved_box.height], edx
  1362.  
  1363.   .exit:
  1364.         pop     esi ebx eax
  1365.         ret
  1366.  
  1367. align 4
  1368. ;------------------------------------------------------------------------------
  1369. window._.set_window_clientbox: ;///////////////////////////////////////////////
  1370. ;------------------------------------------------------------------------------
  1371. ;? <description>
  1372. ;------------------------------------------------------------------------------
  1373. ;> edi = pointer to WDATA struct
  1374. ;------------------------------------------------------------------------------
  1375.         push    eax ecx edi
  1376.  
  1377.         mov     eax, [_skinh]
  1378.         mov     [window_topleft + 8 * 3 + 4], eax
  1379.         mov     [window_topleft + 8 * 4 + 4], eax
  1380.  
  1381.         mov     ecx, edi
  1382.         sub     edi, window_data
  1383.         shl     edi, 3
  1384.         test    [ecx + WDATA.fl_wstyle], WSTYLE_CLIENTRELATIVE
  1385.         jz      .whole_window
  1386.  
  1387.         movzx   eax, [ecx + WDATA.fl_wstyle]
  1388.         and     eax, 0x0F
  1389.         mov     eax, [eax * 8 + window_topleft + 0]
  1390.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
  1391.         shl     eax, 1
  1392.         neg     eax
  1393.         add     eax, [ecx + WDATA.box.width]
  1394.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
  1395.  
  1396.         movzx   eax, [ecx + WDATA.fl_wstyle]
  1397.         and     eax, 0x0F
  1398.         push    [eax * 8 + window_topleft + 0]
  1399.         mov     eax, [eax * 8 + window_topleft + 4]
  1400.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
  1401.         neg     eax
  1402.         sub     eax, [esp]
  1403.         add     eax, [ecx + WDATA.box.height]
  1404.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
  1405.         add     esp, 4
  1406.         jmp     .exit
  1407.  
  1408.   .whole_window:
  1409.         xor     eax, eax
  1410.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.left], eax
  1411.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.top], eax
  1412.         mov     eax, [ecx + WDATA.box.width]
  1413.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.width], eax
  1414.         mov     eax, [ecx + WDATA.box.height]
  1415.         mov     [edi + SLOT_BASE + APPDATA.wnd_clientbox.height], eax
  1416.  
  1417.   .exit:
  1418.         pop     edi ecx eax
  1419.         ret
  1420.  
  1421. align 4
  1422. ;------------------------------------------------------------------------------
  1423. window._.sys_set_window: ;/////////////////////////////////////////////////////
  1424. ;------------------------------------------------------------------------------
  1425. ;? <description>
  1426. ;------------------------------------------------------------------------------
  1427. ;< edx = pointer to WDATA struct
  1428. ;------------------------------------------------------------------------------
  1429.         mov     eax, [CURRENT_TASK]
  1430.         shl     eax, 5
  1431.         add     eax, window_data
  1432.  
  1433.         ; save window colors
  1434.         mov     [eax + WDATA.cl_workarea], edx
  1435.         mov     [eax + WDATA.cl_titlebar], esi
  1436.         mov     [eax + WDATA.cl_frames], edi
  1437.  
  1438.         mov     edi, eax
  1439.  
  1440.         ; was it already defined before?
  1441.         test    [edi + WDATA.fl_wdrawn], 1
  1442.         jnz     .set_client_box
  1443.         or      [edi + WDATA.fl_wdrawn], 1
  1444.  
  1445.         ; NOTE: commented out since doesn't provide necessary functionality
  1446.         ;       anyway, to be reworked
  1447. ;       mov     eax, [timer_ticks] ; [0xfdf0]
  1448. ;       add     eax, 100
  1449. ;       mov     [new_window_starting], eax
  1450.  
  1451.         ; no it wasn't, performing initial window definition
  1452.         movzx   eax, bx
  1453.         mov     [edi + WDATA.box.width], eax
  1454.         movzx   eax, cx
  1455.         mov     [edi + WDATA.box.height], eax
  1456.         sar     ebx, 16
  1457.         sar     ecx, 16
  1458.         mov     [edi + WDATA.box.left], ebx
  1459.         mov     [edi + WDATA.box.top], ecx
  1460.  
  1461.         call    window._.check_window_position
  1462.  
  1463.         push    ecx edi
  1464.  
  1465.         mov     cl, [edi + WDATA.fl_wstyle]
  1466.         mov     eax, [edi + WDATA.cl_frames]
  1467.  
  1468.         sub     edi, window_data
  1469.         shl     edi, 3
  1470.         add     edi, SLOT_BASE
  1471.  
  1472.         and     cl, 0x0F
  1473.         cmp     cl, 3
  1474.         je      @f
  1475.         cmp     cl, 4
  1476.         je      @f
  1477.  
  1478.         xor     eax, eax
  1479.  
  1480.     @@: mov     [edi + APPDATA.wnd_caption], eax
  1481.  
  1482.         mov     esi, [esp]
  1483.         add     edi, APPDATA.saved_box
  1484.         movsd
  1485.         movsd
  1486.         movsd
  1487.         movsd
  1488.  
  1489.         pop     edi ecx
  1490.  
  1491.         mov     esi, [CURRENT_TASK]
  1492.         movzx   esi, word[WIN_STACK + esi * 2]
  1493.         lea     esi, [WIN_POS + esi * 2]
  1494.         call    waredraw
  1495.  
  1496.         mov     eax, [edi + WDATA.box.left]
  1497.         mov     ebx, [edi + WDATA.box.top]
  1498.         mov     ecx, [edi + WDATA.box.width]
  1499.         mov     edx, [edi + WDATA.box.height]
  1500.         add     ecx, eax
  1501.         add     edx, ebx
  1502.         call    calculatescreen
  1503.  
  1504.         mov     byte[KEY_COUNT], 0           ; empty keyboard buffer
  1505.         mov     byte[BTN_COUNT], 0           ; empty button buffer
  1506.  
  1507.   .set_client_box:
  1508.         ; update window client box coordinates
  1509.         call    window._.set_window_clientbox
  1510.  
  1511.         ; reset window redraw flag and exit
  1512.         mov     [edi + WDATA.fl_redraw], 0
  1513.         mov     edx, edi
  1514.         ret
  1515.  
  1516. align 4
  1517. ;------------------------------------------------------------------------------
  1518. window._.check_window_position: ;//////////////////////////////////////////////
  1519. ;------------------------------------------------------------------------------
  1520. ;? Check if window is inside screen area
  1521. ;------------------------------------------------------------------------------
  1522. ;> edi = pointer to WDATA
  1523. ;------------------------------------------------------------------------------
  1524.         push    eax ebx ecx edx esi
  1525.  
  1526.         mov     eax, [edi + WDATA.box.left]
  1527.         mov     ebx, [edi + WDATA.box.top]
  1528.         mov     ecx, [edi + WDATA.box.width]
  1529.         mov     edx, [edi + WDATA.box.height]
  1530.  
  1531.         mov     esi, [Screen_Max_X]
  1532.         cmp     ecx, esi
  1533.         ja      .fix_width_high
  1534.  
  1535.   .check_left:
  1536.         or      eax, eax
  1537.         jl      .fix_left_low
  1538.         add     eax, ecx
  1539.         cmp     eax, esi
  1540.         jg      .fix_left_high
  1541.  
  1542.   .check_height:
  1543.         mov     esi, [Screen_Max_Y]
  1544.         cmp     edx, esi
  1545.         ja      .fix_height_high
  1546.  
  1547.   .check_top:
  1548.         or      ebx, ebx
  1549.         jl      .fix_top_low
  1550.         add     ebx, edx
  1551.         cmp     ebx, esi
  1552.         jg      .fix_top_high
  1553.  
  1554.   .exit:
  1555.         pop     esi edx ecx ebx eax
  1556.         ret
  1557.  
  1558.   .fix_width_high:
  1559.         mov     ecx, esi
  1560.         mov     [edi + WDATA.box.width], esi
  1561.         jmp     .check_left
  1562.  
  1563.   .fix_left_low:
  1564.         xor     eax, eax
  1565.         mov     [edi + WDATA.box.left], eax
  1566.         jmp     .check_height
  1567.  
  1568.   .fix_left_high:
  1569.         mov     eax, esi
  1570.         sub     eax, ecx
  1571.         mov     [edi + WDATA.box.left], eax
  1572.         jmp     .check_height
  1573.  
  1574.   .fix_height_high:
  1575.         mov     edx, esi
  1576.         mov     [edi + WDATA.box.height], esi
  1577.         jmp     .check_top
  1578.  
  1579.   .fix_top_low:
  1580.         xor     ebx, ebx
  1581.         mov     [edi + WDATA.box.top], ebx
  1582.         jmp     .exit
  1583.  
  1584.   .fix_top_high:
  1585.         mov     ebx, esi
  1586.         sub     ebx, edx
  1587.         mov     [edi + WDATA.box.top], ebx
  1588.         jmp     .exit
  1589.  
  1590. align 4
  1591. ;------------------------------------------------------------------------------
  1592. window._.get_titlebar_height: ;////////////////////////////////////////////////
  1593. ;------------------------------------------------------------------------------
  1594. ;? <description>
  1595. ;------------------------------------------------------------------------------
  1596. ;> edi = pointer to WDATA
  1597. ;------------------------------------------------------------------------------
  1598.         mov     al, [edi + WDATA.fl_wstyle]
  1599.         and     al, 0x0f
  1600.         cmp     al, 0x03
  1601.         jne     @f
  1602.         mov     eax, [_skinh]
  1603.         ret
  1604.     @@: mov     eax, 21
  1605.         ret
  1606.  
  1607. align 4
  1608. ;------------------------------------------------------------------------------
  1609. window._.get_rolledup_height: ;////////////////////////////////////////////////
  1610. ;------------------------------------------------------------------------------
  1611. ;? <description>
  1612. ;------------------------------------------------------------------------------
  1613. ;> edi = pointer to WDATA
  1614. ;------------------------------------------------------------------------------
  1615.         mov     al, [edi + WDATA.fl_wstyle]
  1616.         and     al, 0x0f
  1617.         cmp     al, 0x03
  1618.         jb      @f
  1619.         mov     eax, [_skinh]
  1620.         add     eax, 3
  1621.         ret
  1622.     @@: or      al, al
  1623.         jnz     @f
  1624.         mov     eax, 21
  1625.         ret
  1626.     @@: mov     eax, 21 + 2
  1627.         ret
  1628.  
  1629. align 4
  1630. ;------------------------------------------------------------------------------
  1631. window._.set_screen: ;/////////////////////////////////////////////////////////
  1632. ;------------------------------------------------------------------------------
  1633. ;? Reserve window area in screen buffer
  1634. ;------------------------------------------------------------------------------
  1635. ;> eax = left
  1636. ;> ebx = top
  1637. ;> ecx = right
  1638. ;> edx = bottom
  1639. ;> esi = process number
  1640. ;------------------------------------------------------------------------------
  1641. virtual at esp
  1642.   ff_x     dd ?
  1643.   ff_y     dd ?
  1644.   ff_width dd ?
  1645.   ff_xsz   dd ?
  1646.   ff_ysz   dd ?
  1647.   ff_scale dd ?
  1648. end virtual
  1649.  
  1650.         pushad
  1651.  
  1652.         cmp     esi, 1
  1653.         jz      .check_for_shaped_window
  1654.         mov     edi, esi
  1655.         shl     edi, 5
  1656.         cmp     [window_data + edi + WDATA.box.width], 0
  1657.         jnz     .check_for_shaped_window
  1658.         cmp     [window_data + edi + WDATA.box.height], 0
  1659.         jz      .exit
  1660.  
  1661.   .check_for_shaped_window:
  1662.         mov     edi, esi
  1663.         shl     edi, 8
  1664.         add     edi, SLOT_BASE
  1665.         cmp     [edi + APPDATA.wnd_shape], 0
  1666.         jne     .shaped_window
  1667.  
  1668.         ; get x&y size
  1669.         sub     ecx, eax
  1670.         sub     edx, ebx
  1671.         inc     ecx
  1672.         inc     edx
  1673.  
  1674.         ; get WinMap start
  1675.         push    esi
  1676.         mov     edi, [Screen_Max_X]
  1677.         inc     edi
  1678.         mov     esi, edi
  1679.         imul    edi, ebx
  1680.         add     edi, eax
  1681.         add     edi, [_WinMapAddress]
  1682.         pop     eax
  1683.         mov     ah, al
  1684.         push    ax
  1685.         shl     eax, 16
  1686.         pop     ax
  1687.  
  1688.   .next_line:
  1689.         push    ecx
  1690.         shr     ecx, 2
  1691.         rep     stosd
  1692.         mov     ecx, [esp]
  1693.         and     ecx, 3
  1694.         rep     stosb
  1695.         pop     ecx
  1696.         add     edi, esi
  1697.         sub     edi, ecx
  1698.         dec     edx
  1699.         jnz     .next_line
  1700.  
  1701.         jmp     .exit
  1702.  
  1703.   .shaped_window:
  1704.         ;  for (y=0; y <= x_size; y++)
  1705.         ;      for (x=0; x <= x_size; x++)
  1706.         ;          if (shape[coord(x,y,scale)]==1)
  1707.         ;             set_pixel(x, y, process_number);
  1708.  
  1709.         sub     ecx, eax
  1710.         sub     edx, ebx
  1711.         inc     ecx
  1712.         inc     edx
  1713.  
  1714.         push    [edi + APPDATA.wnd_shape_scale]  ; push scale first -> for loop
  1715.  
  1716.         ; get WinMap start  -> ebp
  1717.         push    eax
  1718.         mov     eax, [Screen_Max_X] ; screen_sx
  1719.         inc     eax
  1720.         imul    eax, ebx
  1721.         add     eax, [esp]
  1722.         add     eax, [_WinMapAddress]
  1723.         mov     ebp, eax
  1724.  
  1725.         mov     edi, [edi + APPDATA.wnd_shape]
  1726.         pop     eax
  1727.  
  1728.         ; eax = x_start
  1729.         ; ebx = y_start
  1730.         ; ecx = x_size
  1731.         ; edx = y_size
  1732.         ; esi = process_number
  1733.         ; edi = &shape
  1734.         ;       [scale]
  1735.         push    edx ecx ; for loop - x,y size
  1736.  
  1737.         mov     ecx, esi
  1738.         shl     ecx, 5
  1739.         mov     edx, [window_data + ecx + WDATA.box.top]
  1740.         push    [window_data + ecx + WDATA.box.width]           ; for loop - width
  1741.         mov     ecx, [window_data + ecx + WDATA.box.left]
  1742.         sub     ebx, edx
  1743.         sub     eax, ecx
  1744.         push    ebx eax ; for loop - x,y
  1745.  
  1746.         add     [ff_xsz], eax
  1747.         add     [ff_ysz], ebx
  1748.  
  1749.         mov     ebx, [ff_y]
  1750.  
  1751.   .ff_new_y:
  1752.         mov     edx, [ff_x]
  1753.  
  1754.   .ff_new_x:
  1755.         ; -- body --
  1756.         mov     ecx, [ff_scale]
  1757.         mov     eax, [ff_width]
  1758.         inc     eax
  1759.         shr     eax, cl
  1760.         push    ebx edx
  1761.         shr     ebx, cl
  1762.         shr     edx, cl
  1763.         imul    eax, ebx
  1764.         add     eax, edx
  1765.         pop     edx ebx
  1766.         add     eax, edi
  1767.         call    .read_byte
  1768.         test    al,al
  1769.         jz      @f
  1770.         mov     eax, esi
  1771.         mov     [ebp], al
  1772.         ; -- end body --
  1773.     @@: inc     ebp
  1774.         inc     edx
  1775.         cmp     edx, [ff_xsz]
  1776.         jb      .ff_new_x
  1777.  
  1778.         sub     ebp, [ff_xsz]
  1779.         add     ebp, [ff_x]
  1780.         add     ebp, [Screen_Max_X]  ; screen.x
  1781.         inc     ebp
  1782.         inc     ebx
  1783.         cmp     ebx, [ff_ysz]
  1784.         jb      .ff_new_y
  1785.  
  1786.         add     esp, 24
  1787.  
  1788.   .exit:
  1789.         popad
  1790.         ret
  1791.  
  1792.   .read_byte:
  1793.         ; eax - address
  1794.         ; esi - slot
  1795.         push    eax ecx edx esi
  1796.         xchg    eax, esi
  1797.         lea     ecx, [esp + 12]
  1798.         mov     edx, 1
  1799.         call    read_process_memory
  1800.         pop     esi edx ecx eax
  1801.         ret
  1802.  
  1803. align 4
  1804. ;------------------------------------------------------------------------------
  1805. window._.window_activate: ;////////////////////////////////////////////////////
  1806. ;------------------------------------------------------------------------------
  1807. ;? Activate window
  1808. ;------------------------------------------------------------------------------
  1809. ;> esi = pointer to WIN_POS+ window data
  1810. ;------------------------------------------------------------------------------
  1811.         push    eax ebx
  1812.  
  1813.         ; if type of current active window is 3 or 4, it must be redrawn
  1814.         mov     ebx, [TASK_COUNT]
  1815.         movzx   ebx, word[WIN_POS + ebx * 2]
  1816.         shl     ebx, 5
  1817.         add     eax, window_data
  1818.         mov     al, [window_data + ebx + WDATA.fl_wstyle]
  1819.         and     al, 0x0f
  1820.         cmp     al, 0x03
  1821.         je      .set_window_redraw_flag
  1822.         cmp     al, 0x04
  1823.         jne     .move_others_down
  1824.  
  1825.   .set_window_redraw_flag:
  1826.         mov     [window_data + ebx + WDATA.fl_redraw], 1
  1827.  
  1828.   .move_others_down:
  1829.         ; ax <- process no
  1830.         movzx   ebx, word[esi]
  1831.         ; ax <- position in window stack
  1832.         movzx   ebx, word[WIN_STACK + ebx * 2]
  1833.  
  1834.         ; drop others
  1835.         xor     eax, eax
  1836.  
  1837.   .next_stack_window:
  1838.         cmp     eax, [TASK_COUNT]
  1839.         jae     .move_self_up
  1840.         inc     eax
  1841.         cmp     [WIN_STACK + eax * 2], bx
  1842.         jbe     .next_stack_window
  1843.         dec     word[WIN_STACK + eax * 2]
  1844.         jmp     .next_stack_window
  1845.  
  1846.   .move_self_up:
  1847.         movzx   ebx, word[esi]
  1848.         ; number of processes
  1849.         mov     ax, [TASK_COUNT]
  1850.         ; this is the last (and the upper)
  1851.         mov     [WIN_STACK + ebx * 2], ax
  1852.  
  1853.         ; update on screen - window stack
  1854.         xor     eax, eax
  1855.  
  1856.   .next_window_pos:
  1857.         cmp     eax, [TASK_COUNT]
  1858.         jae     .reset_vars
  1859.         inc     eax
  1860.         movzx   ebx, word[WIN_STACK + eax * 2]
  1861.         mov     [WIN_POS + ebx * 2], ax
  1862.         jmp     .next_window_pos
  1863.  
  1864.   .reset_vars:
  1865.         mov     byte[KEY_COUNT], 0
  1866.         mov     byte[BTN_COUNT], 0
  1867.         mov     word[MOUSE_SCROLL_H], 0
  1868.         mov     word[MOUSE_SCROLL_V], 0
  1869.  
  1870.         pop     ebx eax
  1871.         ret
  1872.  
  1873. align 4
  1874. ;------------------------------------------------------------------------------
  1875. window._.check_window_draw: ;//////////////////////////////////////////////////
  1876. ;------------------------------------------------------------------------------
  1877. ;? Check if window is necessary to draw
  1878. ;------------------------------------------------------------------------------
  1879. ;> edi = pointer to WDATA
  1880. ;------------------------------------------------------------------------------
  1881.         mov     cl, [edi + WDATA.fl_wstyle]
  1882.         and     cl, 0x0f
  1883.         cmp     cl, 3
  1884.         je      .exit.redraw      ; window type 3
  1885.         cmp     cl, 4
  1886.         je      .exit.redraw      ; window type 4
  1887.  
  1888.         push    eax ebx edx esi
  1889.  
  1890.         mov     eax, edi
  1891.         sub     eax, window_data
  1892.         shr     eax, 5
  1893.  
  1894.         movzx   eax, word[WIN_STACK + eax * 2]  ; get value of the curr process
  1895.         lea     esi, [WIN_POS + eax * 2]        ; get address of this process at 0xC400
  1896.  
  1897.   .next_window:
  1898.         add     esi, 2
  1899.  
  1900.         mov     eax, [TASK_COUNT]
  1901.         lea     eax, word[WIN_POS + eax * 2] ; number of the upper window
  1902.  
  1903.         cmp     esi, eax
  1904.         ja      .exit.no_redraw
  1905.  
  1906.         movzx   edx, word[esi]
  1907.         shl     edx, 5
  1908.         cmp     [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
  1909.         je      .next_window
  1910.  
  1911.         mov     eax, [edi + WDATA.box.top]
  1912.         mov     ebx, [edi + WDATA.box.height]
  1913.         add     ebx, eax
  1914.  
  1915.         mov     ecx, [window_data + edx + WDATA.box.top]
  1916.         cmp     ecx, ebx
  1917.         jge     .next_window
  1918.         add     ecx, [window_data + edx + WDATA.box.height]
  1919.         cmp     eax, ecx
  1920.         jge     .next_window
  1921.  
  1922.         mov     eax, [edi + WDATA.box.left]
  1923.         mov     ebx, [edi + WDATA.box.width]
  1924.         add     ebx, eax
  1925.  
  1926.         mov     ecx, [window_data + edx + WDATA.box.left]
  1927.         cmp     ecx, ebx
  1928.         jge     .next_window
  1929.         add     ecx, [window_data + edx + WDATA.box.width]
  1930.         cmp     eax, ecx
  1931.         jge     .next_window
  1932.  
  1933.         pop     esi edx ebx eax
  1934.  
  1935.   .exit.redraw:
  1936.         xor     ecx, ecx
  1937.         inc     ecx
  1938.         ret
  1939.  
  1940.   .exit.no_redraw:
  1941.         pop     esi edx ebx eax
  1942.         xor     ecx, ecx
  1943.         ret
  1944.  
  1945. align 4
  1946. ;------------------------------------------------------------------------------
  1947. window._.draw_window_caption: ;////////////////////////////////////////////////
  1948. ;------------------------------------------------------------------------------
  1949. ;? <description>
  1950. ;------------------------------------------------------------------------------
  1951.         inc     [mouse_pause]
  1952.         call    [_display.disable_mouse]
  1953.  
  1954.         xor     eax, eax
  1955.         mov     edx, [TASK_COUNT]
  1956.         movzx   edx, word[WIN_POS + edx * 2]
  1957.         cmp     edx, [CURRENT_TASK]
  1958.         jne     @f
  1959.         inc     eax
  1960.     @@: mov     edx, [CURRENT_TASK]
  1961.         shl     edx, 5
  1962.         add     edx, window_data
  1963.         movzx   ebx, [edx + WDATA.fl_wstyle]
  1964.         and     bl, 0x0F
  1965.         cmp     bl, 3
  1966.         je      .draw_caption_style_3
  1967.         cmp     bl, 4
  1968.         je      .draw_caption_style_3
  1969.  
  1970.         jmp     .not_style_3
  1971.  
  1972.   .draw_caption_style_3:
  1973.         push    edx
  1974.         call    drawwindow_IV_caption
  1975.         add     esp, 4
  1976.         jmp     .2
  1977.  
  1978.   .not_style_3:
  1979.         cmp     bl, 2
  1980.         jne     .not_style_2
  1981.  
  1982.         call    drawwindow_III_caption
  1983.         jmp     .2
  1984.  
  1985.   .not_style_2:
  1986.         cmp     bl, 0
  1987.         jne     .2
  1988.  
  1989.         call    drawwindow_I_caption
  1990.  
  1991.   .2:   mov     edi, [CURRENT_TASK]
  1992.         shl     edi, 5
  1993.         test    [edi + window_data + WDATA.fl_wstyle], WSTYLE_HASCAPTION
  1994.         jz      .exit
  1995.         mov     edx, [edi * 8 + SLOT_BASE + APPDATA.wnd_caption]
  1996.         or      edx, edx
  1997.         jz      .exit
  1998.  
  1999.         movzx   eax, [edi + window_data + WDATA.fl_wstyle]
  2000.         and     al, 0x0F
  2001.         cmp     al, 3
  2002.         je      .skinned
  2003.         cmp     al, 4
  2004.         je      .skinned
  2005.  
  2006.         jmp     .not_skinned
  2007.  
  2008.   .skinned:
  2009.         mov     ebp, [edi + window_data + WDATA.box.left - 2]
  2010.         mov     bp, word[edi + window_data + WDATA.box.top]
  2011.         movzx   eax, word[edi + window_data + WDATA.box.width]
  2012.         sub     ax, [_skinmargins.left]
  2013.         sub     ax, [_skinmargins.right]
  2014.         push    edx
  2015.         cwde
  2016.         cdq
  2017.         mov     ebx, 6
  2018.         idiv    ebx
  2019.         pop     edx
  2020.         or      eax, eax
  2021.         js      .exit
  2022.  
  2023.         mov     esi, eax
  2024.         mov     ebx, dword[_skinmargins.left - 2]
  2025.         mov     bx, word[_skinh]
  2026.         sub     bx, [_skinmargins.bottom]
  2027.         sub     bx, [_skinmargins.top]
  2028.         sar     bx, 1
  2029.         adc     bx, 0
  2030.         add     bx, [_skinmargins.top]
  2031.         add     bx, -3
  2032.         add     ebx, ebp
  2033.         jmp     .dodraw
  2034.  
  2035.   .not_skinned:
  2036.         cmp     al, 1
  2037.         je      .exit
  2038.  
  2039.         mov     ebp, [edi + window_data + WDATA.box.left - 2]
  2040.         mov     bp, word[edi + window_data + WDATA.box.top]
  2041.         movzx   eax, word[edi + window_data + WDATA.box.width]
  2042.         sub     eax, 16
  2043.         push    edx
  2044.         cwde
  2045.         cdq
  2046.         mov     ebx, 6
  2047.         idiv    ebx
  2048.         pop     edx
  2049.         or      eax, eax
  2050.         js      .exit
  2051.  
  2052.         mov     esi, eax
  2053.         mov     ebx, 0x00080007
  2054.         add     ebx, ebp
  2055.  
  2056.   .dodraw:
  2057.         mov     ecx, [common_colours + 16]
  2058.         or      ecx, 0x80000000
  2059.         xor     edi, edi
  2060.         call    dtext_asciiz_esi
  2061.  
  2062.   .exit:
  2063.         dec     [mouse_pause]
  2064.         call    [draw_pointer]
  2065.         ret
  2066.  
  2067. align 4
  2068. ;------------------------------------------------------------------------------
  2069. window._.draw_negative_box: ;//////////////////////////////////////////////////
  2070. ;------------------------------------------------------------------------------
  2071. ;? Draw negative box
  2072. ;------------------------------------------------------------------------------
  2073. ;> edi = pointer to BOX struct
  2074. ;------------------------------------------------------------------------------
  2075.         push    eax ebx esi
  2076.         mov     eax, [edi + BOX.left - 2]
  2077.         mov     ax, word[edi + BOX.left]
  2078.         add     ax, word[edi + BOX.width]
  2079.         mov     ebx, [edi + BOX.top - 2]
  2080.         mov     bx, word[edi + BOX.top]
  2081.         add     bx, word[edi + BOX.height]
  2082.         mov     esi, 0x01000000
  2083.         call    draw_rectangle.forced
  2084.         pop     esi ebx eax
  2085.         ret
  2086.