Subversion Repositories Kolibri OS

Rev

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