Subversion Repositories Kolibri OS

Rev

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

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