Subversion Repositories Kolibri OS

Rev

Rev 1329 | Rev 1368 | 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: 1362 $
  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. ;> eax = 0
  250. ;> ebx = shape data address
  251. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  252. ;; Set window shape scale:
  253. ;> eax = 1
  254. ;> ebx = scale power (resulting scale is 2^ebx)
  255. ;------------------------------------------------------------------------------
  256.         mov     edi, [current_slot]
  257.  
  258.         test    eax, eax
  259.         jne     .shape_scale
  260.         mov     [edi + APPDATA.wnd_shape], ebx
  261.  
  262.   .shape_scale:
  263.         dec     eax
  264.         jnz     .exit
  265.         mov     [edi + APPDATA.wnd_shape_scale], ebx
  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.         ja      .skip_window
  331.         mov     ebx, [edi + WDATA.box.top]
  332.         cmp     ebx, [esp + RECT.bottom]
  333.         ja      .skip_window
  334.         mov     ecx, [edi + WDATA.box.width]
  335.         add     ecx, eax
  336.         cmp     ecx, [esp + RECT.left]
  337.         jb      .skip_window
  338.         mov     edx, [edi + WDATA.box.height]
  339.         add     edx, ebx
  340.         cmp     edx, [esp + RECT.top]
  341.         jb      .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.         jbe     .check_left
  458.         mov     ecx, esi
  459.         mov     [edi + WDATA.box.width], esi
  460.  
  461.   .check_left:
  462.         or      eax, eax
  463.         jg      @f
  464.         xor     eax, eax
  465.         jmp     .fix_left
  466.     @@: add     eax, ecx
  467.         cmp     eax, esi
  468.         jle     .check_height
  469.         mov     eax, esi
  470.         sub     eax, ecx
  471.  
  472.   .fix_left:
  473.         mov     [edi + WDATA.box.left], eax
  474.  
  475.   .check_height:
  476.         mov     esi, [Screen_Max_Y]
  477.         cmp     edx, esi
  478.         jbe     .check_top
  479.         mov     edx, esi
  480.         mov     [edi + WDATA.box.height], esi
  481.  
  482.   .check_top:
  483.         or      ebx, ebx
  484.         jg      @f
  485.         xor     ebx, ebx
  486.         jmp     .fix_top
  487.     @@: add     ebx, edx
  488.         cmp     ebx, esi
  489.         jle     .exit
  490.         mov     ebx, esi
  491.         sub     ebx, edx
  492.  
  493.   .fix_top:
  494.         mov     [edi + WDATA.box.top], ebx
  495.  
  496.   .exit:
  497.         pop     esi edx ecx ebx eax
  498.         ret
  499.  
  500. align 4
  501. ;------------------------------------------------------------------------------
  502. sys_window_mouse: ;////////////////////////////////////////////////////////////
  503. ;------------------------------------------------------------------------------
  504. ;? <description>
  505. ;------------------------------------------------------------------------------
  506.         push    eax
  507.  
  508.         mov     eax, [timer_ticks]
  509.         cmp     [new_window_starting], eax
  510.         jb      .exit
  511.  
  512.         mov     byte[MOUSE_BACKGROUND], 0
  513.         mov     byte[DONT_DRAW_MOUSE], 0
  514.  
  515.         mov     [new_window_starting], eax
  516.  
  517.   .exit:
  518.         pop     eax
  519.         ret
  520.  
  521. align 4
  522. ;------------------------------------------------------------------------------
  523. draw_rectangle: ;//////////////////////////////////////////////////////////////
  524. ;------------------------------------------------------------------------------
  525. ;> eax = pack[16(left), 16(right)]
  526. ;> ebx = pack[16(top), 16(bottom)]
  527. ;> esi = color
  528. ;------------------------------------------------------------------------------
  529.         push    eax ebx ecx edi
  530.  
  531.         xor     edi, edi
  532.  
  533.   .flags_set:
  534.         push    ebx
  535.  
  536.         ; set line color
  537.         mov     ecx, esi
  538.  
  539.         ; draw top border
  540.         rol     ebx, 16
  541.         push    ebx
  542.         rol     ebx, 16
  543.         pop     bx
  544.         call    [draw_line]
  545.  
  546.         ; draw bottom border
  547.         mov     ebx, [esp - 2]
  548.         pop     bx
  549.         call    [draw_line]
  550.  
  551.         pop     ebx
  552.         add     ebx, 1 * 65536 - 1
  553.  
  554.         ; draw left border
  555.         rol     eax, 16
  556.         push    eax
  557.         rol     eax, 16
  558.         pop     ax
  559.         call    [draw_line]
  560.  
  561.         ; draw right border
  562.         mov     eax, [esp - 2]
  563.         pop     ax
  564.         call    [draw_line]
  565.  
  566.         pop     edi ecx ebx eax
  567.         ret
  568.  
  569.   .forced:
  570.         push    eax ebx ecx edi
  571.         xor     edi, edi
  572.         inc     edi
  573.         jmp     .flags_set
  574.  
  575. align 4
  576. ;------------------------------------------------------------------------------
  577. drawwindow_I_caption: ;////////////////////////////////////////////////////////
  578. ;------------------------------------------------------------------------------
  579. ;? <description>
  580. ;------------------------------------------------------------------------------
  581.         push    [edx + WDATA.cl_titlebar]
  582.         mov     esi, edx
  583.  
  584.         mov     edx, [esi + WDATA.box.top]
  585.         mov     eax, edx
  586.         lea     ebx, [edx + 21]
  587.         inc     edx
  588.         add     eax, [esi + WDATA.box.height]
  589.  
  590.         cmp     ebx, eax
  591.         jbe     @f
  592.         mov     ebx, eax
  593.     @@: push    ebx
  594.  
  595.         xor     edi, edi
  596.  
  597.   .next_line:
  598.         mov     ebx, edx
  599.         shl     ebx, 16
  600.         add     ebx, edx
  601.         mov     eax, [esi + WDATA.box.left]
  602.         inc     eax
  603.         shl     eax, 16
  604.         add     eax, [esi + WDATA.box.left]
  605.         add     eax, [esi + WDATA.box.width]
  606.         dec     eax
  607.         mov     ecx, [esi + WDATA.cl_titlebar]
  608.         test    ecx, 0x80000000
  609.         jz      @f
  610.         sub     ecx, 0x00040404
  611.         mov     [esi + WDATA.cl_titlebar], ecx
  612.     @@: and     ecx, 0x00ffffff
  613.         call    [draw_line]
  614.         inc     edx
  615.         cmp     edx, [esp]
  616.         jb      .next_line
  617.  
  618.         add     esp, 4
  619.         pop     [esi + WDATA.cl_titlebar]
  620.         ret
  621.  
  622. align 4
  623. ;------------------------------------------------------------------------------
  624. drawwindow_I: ;////////////////////////////////////////////////////////////////
  625. ;------------------------------------------------------------------------------
  626. ;? <description>
  627. ;------------------------------------------------------------------------------
  628.         pushad
  629.  
  630.         ; window border
  631.  
  632.         mov     eax, [edx + WDATA.box.left - 2]
  633.         mov     ax, word[edx + WDATA.box.left]
  634.         add     ax, word[edx + WDATA.box.width]
  635.         mov     ebx, [edx + WDATA.box.top - 2]
  636.         mov     bx, word[edx + WDATA.box.top]
  637.         add     bx, word[edx + WDATA.box.height]
  638.  
  639.         mov     esi, [edx + WDATA.cl_frames]
  640.         call    draw_rectangle
  641.  
  642.         ; window caption
  643.  
  644.         call    drawwindow_I_caption
  645.  
  646.         ; window client area
  647.  
  648.         ; do we need to draw it?
  649.         mov     edi, [esi + WDATA.cl_workarea]
  650.         test    edi, 0x40000000
  651.         jnz     .exit
  652.  
  653.         ; does client area have a positive size on screen?
  654.         mov     edx, [esi + WDATA.box.top]
  655.         add     edx, 21 + 5
  656.         mov     ebx, [esi + WDATA.box.top]
  657.         add     ebx, [esi + WDATA.box.height]
  658.         cmp     edx, ebx
  659.         jg      .exit
  660.  
  661.         ; okay, let's draw it
  662.         mov     eax, 1
  663.         mov     ebx, 21
  664.         mov     ecx, [esi + WDATA.box.width]
  665.         mov     edx, [esi + WDATA.box.height]
  666.         call    [drawbar]
  667.  
  668.   .exit:
  669.         popad
  670.         ret
  671.  
  672. align 4
  673. ;------------------------------------------------------------------------------
  674. drawwindow_III_caption: ;/////////////////////////////////////////////////////
  675. ;------------------------------------------------------------------------------
  676. ;? <description>
  677. ;------------------------------------------------------------------------------
  678.         mov     ecx, [edx + WDATA.cl_titlebar]
  679.         push    ecx
  680.         mov     esi, edx
  681.         mov     edx, [esi + WDATA.box.top]
  682.         add     edx, 4
  683.         mov     ebx, [esi + WDATA.box.top]
  684.         add     ebx, 20
  685.         mov     eax, [esi + WDATA.box.top]
  686.         add     eax, [esi + WDATA.box.height]
  687.  
  688.         cmp     ebx, eax
  689.         jb      @f
  690.         mov     ebx, eax
  691.     @@: push    ebx
  692.  
  693.         xor     edi, edi
  694.  
  695.   .next_line:
  696.         mov     ebx, edx
  697.         shl     ebx, 16
  698.         add     ebx, edx
  699.         mov     eax, [esi + WDATA.box.left]
  700.         shl     eax, 16
  701.         add     eax, [esi + WDATA.box.left]
  702.         add     eax, [esi + WDATA.box.width]
  703.         add     eax, 4 * 65536 - 4
  704.         mov     ecx, [esi + WDATA.cl_titlebar]
  705.         test    ecx, 0x40000000
  706.         jz      @f
  707.         add     ecx, 0x00040404
  708.     @@: test    ecx, 0x80000000
  709.         jz      @f
  710.         sub     ecx, 0x00040404
  711.     @@: mov     [esi + WDATA.cl_titlebar], ecx
  712.         and     ecx, 0x00ffffff
  713.         call    [draw_line]
  714.         inc     edx
  715.         cmp     edx, [esp]
  716.         jb      .next_line
  717.  
  718.         add     esp, 4
  719.         pop     [esi + WDATA.cl_titlebar]
  720.         ret
  721.  
  722. align 4
  723. ;------------------------------------------------------------------------------
  724. drawwindow_III: ;//////////////////////////////////////////////////////////////
  725. ;------------------------------------------------------------------------------
  726. ;? <description>
  727. ;------------------------------------------------------------------------------
  728.         pushad
  729.  
  730.         ; window border
  731.  
  732.         mov     eax, [edx + WDATA.box.left - 2]
  733.         mov     ax, word[edx + WDATA.box.left]
  734.         add     ax, word[edx + WDATA.box.width]
  735.         mov     ebx, [edx + WDATA.box.top - 2]
  736.         mov     bx, word[edx + WDATA.box.top]
  737.         add     bx, word[edx + WDATA.box.height]
  738.  
  739.         mov     esi, [edx + WDATA.cl_frames]
  740.         shr     esi, 1
  741.         and     esi, 0x007f7f7f
  742.         call    draw_rectangle
  743.  
  744.         push    esi
  745.         mov     ecx, 3
  746.         mov     esi, [edx + WDATA.cl_frames]
  747.  
  748.   .next_frame:
  749.         add     eax, 1 * 65536 - 1
  750.         add     ebx, 1 * 65536 - 1
  751.         call    draw_rectangle
  752.         dec     ecx
  753.         jnz     .next_frame
  754.  
  755.         pop     esi
  756.         add     eax, 1 * 65536 - 1
  757.         add     ebx, 1 * 65536 - 1
  758.         call    draw_rectangle
  759.  
  760.         ; window caption
  761.  
  762.         call    drawwindow_III_caption
  763.  
  764.         ; window client area
  765.  
  766.         ; do we need to draw it?
  767.         mov     edi, [esi + WDATA.cl_workarea]
  768.         test    edi, 0x40000000
  769.         jnz     .exit
  770.  
  771.         ; does client area have a positive size on screen?
  772.         mov     edx, [esi + WDATA.box.top]
  773.         add     edx, 21 + 5
  774.         mov     ebx, [esi + WDATA.box.top]
  775.         add     ebx, [esi + WDATA.box.height]
  776.         cmp     edx, ebx
  777.         jg      .exit
  778.  
  779.         ; okay, let's draw it
  780.         mov     eax, 5
  781.         mov     ebx, 20
  782.         mov     ecx, [esi + WDATA.box.width]
  783.         mov     edx, [esi + WDATA.box.height]
  784.         sub     ecx, 4
  785.         sub     edx, 4
  786.         call    [drawbar]
  787.  
  788.   .exit:
  789.         popad
  790.         ret
  791.  
  792. align 4
  793. ;------------------------------------------------------------------------------
  794. waredraw: ;////////////////////////////////////////////////////////////////////
  795. ;------------------------------------------------------------------------------
  796. ;? Activate window, redrawing if necessary
  797. ;------------------------------------------------------------------------------
  798.         ; is it overlapped by another window now?
  799.         push    ecx
  800.         call    window._.check_window_draw
  801.         test    ecx, ecx
  802.         pop     ecx
  803.         jz      .do_not_draw
  804.  
  805.         ; yes it is, activate and update screen buffer
  806.         mov     byte[MOUSE_DOWN], 1
  807.         call    window._.window_activate
  808.  
  809.         pushad
  810.         mov     edi, [TASK_COUNT]
  811.         movzx   esi, word[WIN_POS + edi * 2]
  812.         shl     esi, 5
  813.         add     esi, window_data
  814.  
  815.         mov     eax, [esi + WDATA.box.left]
  816.         mov     ebx, [esi + WDATA.box.top]
  817.         mov     ecx, [esi + WDATA.box.width]
  818.         mov     edx, [esi + WDATA.box.height]
  819.  
  820.         add     ecx, eax
  821.         add     edx, ebx
  822.  
  823.         mov     edi, [TASK_COUNT]
  824.         movzx   esi, word[WIN_POS + edi * 2]
  825.         call    window._.set_screen
  826.         popad
  827.  
  828.         ; tell application to redraw itself
  829.         mov     [edi + WDATA.fl_redraw], 1
  830.         mov     byte[MOUSE_DOWN], 0
  831.         ret
  832.  
  833.   .do_not_draw:
  834.         ; no it's not, just activate the window
  835.         call    window._.window_activate
  836.         mov     byte[MOUSE_DOWN], 0
  837.         mov     byte[MOUSE_BACKGROUND], 0
  838.         mov     byte[DONT_DRAW_MOUSE], 0
  839.         ret
  840.  
  841. align 4
  842. ;------------------------------------------------------------------------------
  843. minimize_window: ;/////////////////////////////////////////////////////////////
  844. ;------------------------------------------------------------------------------
  845. ;> eax = window number on screen
  846. ;------------------------------------------------------------------------------
  847. ;# corrupts [dl*]
  848. ;------------------------------------------------------------------------------
  849.         push    edi
  850.         pushfd
  851.         cli
  852.  
  853.         ; is it already minimized?
  854.         movzx   edi, word[WIN_POS + eax * 2]
  855.         shl     edi, 5
  856.         add     edi, window_data
  857.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  858.         jnz     .exit
  859.  
  860.         push    eax ebx ecx edx esi
  861.  
  862.         ; no it's not, let's do that
  863.         or      [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  864.         mov     eax, [edi + WDATA.box.left]
  865.         mov     [draw_limits.left], eax
  866.         mov     ecx, eax
  867.         add     ecx, [edi + WDATA.box.width]
  868.         mov     [draw_limits.right], ecx
  869.         mov     ebx, [edi + WDATA.box.top]
  870.         mov     [draw_limits.top], ebx
  871.         mov     edx, ebx
  872.         add     edx, [edi + WDATA.box.height]
  873.         mov     [draw_limits.bottom], edx
  874.         call    calculatescreen
  875.         xor     esi, esi
  876.         xor     eax, eax
  877.         call    redrawscreen
  878.  
  879.         pop     esi edx ecx ebx eax
  880.  
  881.   .exit:
  882.         popfd
  883.         pop     edi
  884.         ret
  885.  
  886. align 4
  887. ;------------------------------------------------------------------------------
  888. restore_minimized_window: ;////////////////////////////////////////////////////
  889. ;------------------------------------------------------------------------------
  890. ;> eax = window number on screen
  891. ;------------------------------------------------------------------------------
  892. ;# corrupts [dl*]
  893. ;------------------------------------------------------------------------------
  894.         pushad
  895.         pushfd
  896.         cli
  897.  
  898.         ; is it already restored?
  899.         movzx   esi, word[WIN_POS + eax * 2]
  900.         mov     edi, esi
  901.         shl     edi, 5
  902.         add     edi, window_data
  903.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  904.         jz      .exit
  905.  
  906.         ; no it's not, let's do that
  907.         mov     [edi + WDATA.fl_redraw], 1
  908.         and     [edi + WDATA.fl_wstate], not WSTATE_MINIMIZED
  909.         mov     ebp, window._.set_screen
  910.         cmp     eax, [TASK_COUNT]
  911.         jz      @f
  912.         mov     ebp, calculatescreen
  913.     @@: mov     eax, [edi + WDATA.box.left]
  914.         mov     ebx, [edi + WDATA.box.top]
  915.         mov     ecx, [edi + WDATA.box.width]
  916.         mov     edx, [edi + WDATA.box.height]
  917.         add     ecx, eax
  918.         add     edx, ebx
  919.         call    ebp
  920.  
  921.         mov     byte[MOUSE_BACKGROUND], 0
  922.  
  923.   .exit:
  924.         popfd
  925.         popad
  926.         ret
  927.  
  928. align 4
  929. ;------------------------------------------------------------------------------
  930. checkwindows: ;////////////////////////////////////////////////////////////////
  931. ;------------------------------------------------------------------------------
  932. ;? Check for user-initiated window operations
  933. ;------------------------------------------------------------------------------
  934.         pushad
  935.  
  936.         ; do we have window minimize/restore request?
  937.         cmp     [window_minimize], 0
  938.         je      .check_for_mouse_buttons_state
  939.  
  940.         ; okay, minimize or restore top-most window and exit
  941.         mov     eax, [TASK_COUNT]
  942.         mov     bl, 0
  943.         xchg    [window_minimize], bl
  944.         dec     bl
  945.         jnz     @f
  946.         call    minimize_window
  947.         jmp     .check_for_mouse_buttons_state
  948.     @@: call    restore_minimized_window
  949.  
  950.   .check_for_mouse_buttons_state:
  951.         ; do we have any mouse buttons pressed?
  952.         cmp     byte[BTN_DOWN], 0
  953.         jne     .mouse_buttons_pressed
  954.  
  955.         mov     [bPressedMouseXY_W], 0
  956.         jmp     .exit
  957.  
  958.   .mouse_buttons_pressed:
  959.         ; yes we do, iterate and ...
  960.         mov     esi, [TASK_COUNT]
  961.         inc     esi
  962.  
  963.         cmp     [bPressedMouseXY_W], 1
  964.         ja      .next_window
  965.         inc     [bPressedMouseXY_W]
  966.         jnc     .next_window
  967.         push    dword[MOUSE_X]
  968.         pop     dword[mx]
  969.  
  970.   .next_window:
  971.         cmp     esi, 2
  972.         jb      .exit
  973.  
  974.         dec     esi
  975.  
  976.         ; is that window not minimized?
  977.         movzx   edi, word[WIN_POS + esi * 2]
  978.         shl     edi, 5
  979.         add     edi, window_data
  980.         test    [edi + WDATA.fl_wstate], WSTATE_MINIMIZED
  981.         jnz     .next_window
  982.  
  983.         movzx   eax, [mx]
  984.         movzx   ebx, [my]
  985.  
  986.         ; is the cursor inside screen bounds of that window?
  987.         mov     ecx, [edi + WDATA.box.left]
  988.         mov     edx, [edi + WDATA.box.top]
  989.         cmp     eax, ecx
  990.         jl      .next_window
  991.         cmp     ebx, edx
  992.         jl      .next_window
  993.         add     ecx, [edi + WDATA.box.width]
  994.         add     edx, [edi + WDATA.box.height]
  995.         cmp     eax, ecx
  996.         jge     .next_window
  997.         cmp     ebx, edx
  998.         jge     .next_window
  999.  
  1000.         ; is that a top-most (which means active) window?
  1001.         cmp     esi, [TASK_COUNT]
  1002.         je      .check_for_moving_or_resizing
  1003.  
  1004.         ; no it's not, did we just press mouse button down above it or was it
  1005.         ; already pressed before?
  1006.         cmp     [bPressedMouseXY_W], 1
  1007.         ja      .exit
  1008.  
  1009.         ; okay, we just pressed the button, activate this window and exit
  1010.         lea     esi, [WIN_POS + esi * 2]
  1011.         call    waredraw
  1012.         jmp     .exit
  1013.  
  1014.   .check_for_moving_or_resizing:
  1015.         ; is that window movable?
  1016.         test    byte[edi + WDATA.cl_titlebar + 3], 0x01
  1017.         jnz     .exit
  1018.  
  1019.         ; yes it is, is it rolled up?
  1020.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  1021.         jnz     .check_for_cursor_on_caption
  1022.  
  1023.         ; no it's not, can it be resized then?
  1024.         mov     [do_resize_from_corner], 0
  1025.         mov     dl, [edi + WDATA.fl_wstyle]
  1026.         and     dl, 0x0f
  1027.         cmp     dl, 0x00
  1028.         je      .check_for_cursor_on_caption
  1029.         cmp     dl, 0x01
  1030.         je      .check_for_cursor_on_caption
  1031.         cmp     dl, 0x04
  1032.         je      .check_for_cursor_on_caption
  1033.  
  1034.         ; are we going to resize it?
  1035.         mov     edx, [edi + WDATA.box.top]
  1036.         add     edx, [edi + WDATA.box.height]
  1037.         sub     edx, 6
  1038.         cmp     ebx, edx
  1039.         jl      .check_for_cursor_on_caption
  1040.  
  1041.         ; yes we do, remember that
  1042.         mov     [do_resize_from_corner], 1
  1043.         jmp     .set_move_resize_flag
  1044.  
  1045.   .check_for_cursor_on_caption:
  1046.         ; is the cursor inside window titlebar?
  1047.         push    eax
  1048.         call    window._.get_titlebar_height
  1049.         add     eax, [edi + WDATA.box.top]
  1050.         cmp     ebx, eax
  1051.         pop     eax
  1052.         jge     .exit
  1053.  
  1054.         ; calculate duration between two clicks
  1055.         mov     ecx, [timer_ticks]
  1056.         mov     edx, ecx
  1057.         sub     edx, [latest_window_touch]
  1058.         mov     [latest_window_touch], ecx
  1059.         mov     [latest_window_touch_delta], edx
  1060.  
  1061.   .set_move_resize_flag:
  1062.         mov     cl, [BTN_DOWN]
  1063.         mov     [do_resize], cl
  1064.  
  1065.         mov     ecx, [edi + WDATA.box.left]
  1066.         mov     edx, [edi + WDATA.box.top]
  1067.  
  1068.         push    ecx edx
  1069.         mov     [draw_limits.left], ecx
  1070.         mov     [draw_limits.top], edx
  1071.         add     ecx, [edi + WDATA.box.width]
  1072.         add     edx, [edi + WDATA.box.height]
  1073.         mov     [draw_limits.right], ecx
  1074.         mov     [draw_limits.bottom], edx
  1075.         pop     edx ecx
  1076.  
  1077.         ; calculate window-relative cursor coordinates
  1078.         sub     eax, ecx
  1079.         sub     ebx, edx
  1080.  
  1081.         push    dword[MOUSE_X]
  1082.         pop     dword[WIN_TEMP_XY]
  1083.  
  1084.         ; save old window coordinates
  1085.         push    eax
  1086.         mov     eax, [edi + WDATA.box.left]
  1087.         mov     [old_window_pos.left], eax
  1088.         mov     [new_window_pos.left], eax
  1089.         mov     eax, [edi + WDATA.box.top]
  1090.         mov     [old_window_pos.top], eax
  1091.         mov     [new_window_pos.top], eax
  1092.         mov     eax, [edi + WDATA.box.width]
  1093.         mov     [old_window_pos.width], eax
  1094.         mov     [new_window_pos.width], eax
  1095.         mov     eax, [edi + WDATA.box.height]
  1096.         mov     [old_window_pos.height], eax
  1097.         mov     [new_window_pos.height], eax
  1098.         pop     eax
  1099.  
  1100.         ; draw negative moving/sizing frame
  1101.         call    window._.draw_window_frames
  1102.  
  1103.         mov     [reposition], 0
  1104.         mov     byte[MOUSE_DOWN], 1
  1105.  
  1106.   .next_mouse_state_check:
  1107.         ; process OS events
  1108.         mov     byte[DONT_DRAW_MOUSE], 1
  1109.         call    checkidle
  1110.         call    checkVga_N13
  1111.         mov     byte[MOUSE_BACKGROUND], 0
  1112.         call    [draw_pointer]
  1113.         pushad
  1114.         call    stack_handler
  1115.         popad
  1116.  
  1117.         ; did cursor position change?
  1118.         mov     esi, [WIN_TEMP_XY]
  1119.         cmp     esi, [MOUSE_X]
  1120.         je      .check_for_new_mouse_buttons_state
  1121.  
  1122.         ; yes it did, calculate window-relative cursor coordinates
  1123.         movzx   ecx, word[MOUSE_X]
  1124.         movzx   edx, word[MOUSE_Y]
  1125.         sub     ecx, eax
  1126.         sub     edx, ebx
  1127.  
  1128.         push    eax ebx
  1129.  
  1130.         ; we're going to draw new frame, erasing the old one
  1131.         call    window._.draw_window_frames
  1132.  
  1133.         ; are we moving it right now?
  1134.         cmp     [do_resize_from_corner], 0
  1135.         jne     .resize_window
  1136.  
  1137.         ; yes we do, check if it's inside the screen area
  1138.         mov     eax, [Screen_Max_X]
  1139.         mov     ebx, [Screen_Max_Y]
  1140.  
  1141.         mov     [new_window_pos.left], 0
  1142.         or      ecx, ecx
  1143.         jle     .check_for_new_vert_cursor_pos
  1144.         mov     [reposition], 1
  1145.         sub     eax, [new_window_pos.width]
  1146.         mov     [new_window_pos.left], eax
  1147.         cmp     ecx, eax
  1148.         jge     .check_for_new_vert_cursor_pos
  1149.         mov     [new_window_pos.left], ecx
  1150.  
  1151.   .check_for_new_vert_cursor_pos:
  1152.         mov     [new_window_pos.top], 0
  1153.         or      edx, edx
  1154.         jle     .draw_new_window_frame
  1155.         mov     [reposition], 1
  1156.         sub     ebx, [new_window_pos.height]
  1157.         mov     [new_window_pos.top], ebx
  1158.         cmp     edx, ebx
  1159.         jge     .draw_new_window_frame
  1160.         mov     [new_window_pos.top], edx
  1161.         jmp     .draw_new_window_frame
  1162.  
  1163.   .resize_window:
  1164.         push    eax ebx edx
  1165.  
  1166.         mov     edx, edi
  1167.         sub     edx, window_data
  1168.         lea     edx, [SLOT_BASE + edx * 8]
  1169.  
  1170.         movzx   eax, word[MOUSE_X]
  1171.         cmp     eax, [edi + WDATA.box.left]
  1172.         jb      .fix_new_vert_size
  1173.         sub     eax, [edi + WDATA.box.left]
  1174.         cmp     eax, 32
  1175.         jge     @f
  1176.         mov     eax, 32
  1177.     @@: mov     [new_window_pos.width], eax
  1178.  
  1179.   .fix_new_vert_size:
  1180.         call    window._.get_rolledup_height
  1181.         mov     ebx, eax
  1182.         movzx   eax, word[MOUSE_Y]
  1183.         cmp     eax, [edi + WDATA.box.top]
  1184.         jb      .set_reposition_flag
  1185.         sub     eax, [edi + WDATA.box.top]
  1186.         cmp     eax, ebx
  1187.         jge     @f
  1188.         mov     eax, ebx
  1189.     @@: mov     [new_window_pos.height], eax
  1190.  
  1191.   .set_reposition_flag:
  1192.         mov     [reposition], 1
  1193.  
  1194.         pop     edx ebx eax
  1195.  
  1196.   .draw_new_window_frame:
  1197.         pop     ebx eax
  1198.  
  1199.         ; draw new window moving/sizing frame
  1200.         call    window._.draw_window_frames
  1201.  
  1202.         mov     esi, [MOUSE_X]
  1203.         mov     [WIN_TEMP_XY], esi
  1204.  
  1205.   .check_for_new_mouse_buttons_state:
  1206.         ; did user release mouse button(s)?
  1207.         cmp     byte[BTN_DOWN], 0
  1208.         jne     .next_mouse_state_check
  1209.  
  1210.         ; yes he did, moving/sizing is over
  1211.         mov     byte[DONT_DRAW_MOUSE], 1
  1212.         mov     cl, 0
  1213.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  1214.         jnz     .check_other_actions
  1215.  
  1216.         mov     cl, [reposition]
  1217.  
  1218.         ; draw negative frame once again to hide it
  1219.         call    window._.draw_window_frames
  1220.  
  1221.         ; save new window bounds
  1222.         mov     eax, [new_window_pos.left]
  1223.         mov     [edi + WDATA.box.left], eax
  1224.         mov     eax, [new_window_pos.top]
  1225.         mov     [edi + WDATA.box.top], eax
  1226.         mov     eax, [new_window_pos.width]
  1227.         mov     [edi + WDATA.box.width], eax
  1228.         mov     eax, [new_window_pos.height]
  1229.         mov     [edi + WDATA.box.height], eax
  1230.         call    set_window_clientbox
  1231.  
  1232.         cmp     cl, 1
  1233.         jne     .check_other_actions
  1234.         push    esi edi ecx
  1235.         mov     esi, edi
  1236.         mov     ecx, 2
  1237.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP or WSTATE_MAXIMIZED
  1238.         jnz     @f
  1239.         add     ecx, 2
  1240.     @@: sub     edi, window_data
  1241.         shr     edi, 5
  1242.         shl     edi, 8
  1243.         add     edi, SLOT_BASE + APPDATA.saved_box
  1244.         cld
  1245.         rep     movsd
  1246.         pop     ecx edi esi
  1247.  
  1248.   .check_other_actions:
  1249.         mov     [reposition], cl
  1250.  
  1251.         pushad
  1252.  
  1253.         mov     dl, [edi + WDATA.fl_wstyle]
  1254.         and     dl, 0x0f
  1255.         cmp     dl, 0x00
  1256.         je      .check_if_window_fits_screen
  1257.         cmp     dl, 0x01
  1258.         je      .check_if_window_fits_screen
  1259.  
  1260.         cmp     cl, 1
  1261.         je      .no_window_sizing
  1262.         mov     edx, edi
  1263.         sub     edx, window_data
  1264.         shr     edx, 5
  1265.         shl     edx, 8
  1266.         add     edx, SLOT_BASE
  1267.  
  1268.         ; did we right-click on titlebar?
  1269.         cmp     [do_resize], 2
  1270.         jne     .check_maximization_request
  1271.  
  1272.         ; yes we did, toggle normal/rolled up window state
  1273.         xor     [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  1274.         mov     [reposition], 1
  1275.  
  1276.         ; calculate and set appropriate window height
  1277.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  1278.         jz      @f
  1279.         call    window._.get_rolledup_height
  1280.         jmp     .set_new_window_height
  1281.     @@: mov     eax, [edx + APPDATA.saved_box.height]
  1282.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  1283.         jz      .set_new_window_height
  1284.         mov     eax, [screen_workarea.bottom]
  1285.         sub     eax, [screen_workarea.top]
  1286.  
  1287.   .set_new_window_height:
  1288.         mov     [edi + WDATA.box.height], eax
  1289.         add     eax, [edi + WDATA.box.top]
  1290.         cmp     eax, [Screen_Max_Y]
  1291.         jbe     @f
  1292.         mov     eax, [Screen_Max_Y]
  1293.         sub     eax, [edi + WDATA.box.height]
  1294.         mov     [edi + WDATA.box.top], eax
  1295.     @@: call    check_window_position
  1296.         call    set_window_clientbox
  1297.  
  1298.   .check_maximization_request:
  1299.         ; can window change its height?
  1300.         push    edx
  1301.         mov     dl, [edi + WDATA.fl_wstyle]
  1302.         and     dl, 0x0f
  1303.         cmp     dl, 0x04
  1304.         pop     edx
  1305.         je      .check_if_window_fits_screen
  1306.  
  1307.         ; was it really a maximize/restore request?
  1308.         cmp     [do_resize], 1
  1309.         jne     .check_if_window_fits_screen
  1310.         cmp     [do_resize_from_corner], 0
  1311.         jne     .check_if_window_fits_screen
  1312.         cmp     [latest_window_touch_delta], 50
  1313.         jg      .check_if_window_fits_screen
  1314.  
  1315.         ; yes is was, toggle normal/maximized window state
  1316.         xor     [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  1317.         mov     [reposition], 1
  1318.  
  1319.         ; calculate and set appropriate window bounds
  1320.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  1321.         jz      .restore_normal_window_size
  1322.         mov     eax, [screen_workarea.left]
  1323.         mov     [edi + WDATA.box.left], eax
  1324.         sub     eax, [screen_workarea.right]
  1325.         neg     eax
  1326.         mov     [edi + WDATA.box.width], eax
  1327.         mov     eax, [screen_workarea.top]
  1328.         mov     [edi + WDATA.box.top], eax
  1329.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  1330.         jnz     .calculate_window_client_area
  1331.         sub     eax, [screen_workarea.bottom]
  1332.         neg     eax
  1333.         mov     [edi + WDATA.box.height], eax
  1334.         jmp     .calculate_window_client_area
  1335.  
  1336.   .restore_normal_window_size:
  1337.         push    [edi + WDATA.box.height]
  1338.         push    edi
  1339.         lea     esi, [edx + APPDATA.saved_box]
  1340.         mov     ecx, 4
  1341.         cld
  1342.         rep     movsd
  1343.         pop     edi
  1344.         pop     eax
  1345.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  1346.         jz      .calculate_window_client_area
  1347.         mov     [edi + WDATA.box.height], eax
  1348.  
  1349.   .calculate_window_client_area:
  1350.         call    set_window_clientbox
  1351.  
  1352.   .check_if_window_fits_screen:
  1353.         ; does window fit into screen area?
  1354.         mov     eax, [edi + WDATA.box.top]
  1355.         add     eax, [edi + WDATA.box.height]
  1356.         cmp     eax, [Screen_Max_Y]
  1357.         jbe     .no_window_sizing
  1358.         mov     eax, [edi + WDATA.box.left]
  1359.         add     eax, [edi + WDATA.box.width]
  1360.         cmp     eax, [Screen_Max_X]
  1361.         jbe     .no_window_sizing
  1362.  
  1363.         ; no it doesn't, fix that
  1364.         mov     eax, [Screen_Max_X]
  1365.         sub     eax, [edi + WDATA.box.width]
  1366.         mov     [edi + WDATA.box.left], eax
  1367.         mov     eax, [Screen_Max_Y]
  1368.         sub     eax, [edi + WDATA.box.height]
  1369.         mov     [edi + WDATA.box.top], eax
  1370.         call    set_window_clientbox
  1371.  
  1372.   .no_window_sizing:
  1373.         popad
  1374.  
  1375.         ; did somethins actually change its place?
  1376.         cmp     [reposition], 0
  1377.         je      .reset_vars
  1378.  
  1379.         mov     byte[DONT_DRAW_MOUSE], 1
  1380.  
  1381.         push    eax ebx ecx edx
  1382.  
  1383.         ; recalculate screen buffer at new position
  1384.         mov     eax, [edi + WDATA.box.left]
  1385.         mov     ebx, [edi + WDATA.box.top]
  1386.         mov     ecx, [edi + WDATA.box.width]
  1387.         mov     edx, [edi + WDATA.box.height]
  1388.         add     ecx, eax
  1389.         add     edx, ebx
  1390.         call    calculatescreen
  1391.  
  1392.         ; recalculate screen buffer at old position
  1393.         mov     eax, [old_window_pos.left]
  1394.         mov     ebx, [old_window_pos.top]
  1395.         mov     ecx, [old_window_pos.width]
  1396.         mov     edx, [old_window_pos.height]
  1397.         add     ecx, eax
  1398.         add     edx, ebx
  1399.         call    calculatescreen
  1400.  
  1401.         pop     edx ecx ebx eax
  1402.  
  1403.         mov     eax, edi
  1404.         call    redrawscreen
  1405.  
  1406.         ; tell window to redraw itself
  1407.         mov     [edi + WDATA.fl_redraw], 1
  1408.  
  1409.         ; wait a bit for window to redraw itself
  1410.         mov     ecx, 100
  1411.  
  1412.   .next_idle_cycle:
  1413.         mov     byte[DONT_DRAW_MOUSE], 1
  1414.         call    checkidle
  1415.         cmp     [edi + WDATA.fl_redraw], 0
  1416.         jz      .reset_vars
  1417.         loop    .next_idle_cycle
  1418.  
  1419.   .reset_vars:
  1420.         mov     byte[DONT_DRAW_MOUSE], 0 ; mouse pointer
  1421.         mov     byte[MOUSE_BACKGROUND], 0 ; no mouse under
  1422.         mov     byte[MOUSE_DOWN], 0 ; react to mouse up/down
  1423.  
  1424.   .exit:
  1425.         popad
  1426.         ret
  1427.  
  1428. ;==============================================================================
  1429. ;///// private functions //////////////////////////////////////////////////////
  1430. ;==============================================================================
  1431.  
  1432. align 4
  1433. ;------------------------------------------------------------------------------
  1434. window._.get_titlebar_height: ;////////////////////////////////////////////////
  1435. ;------------------------------------------------------------------------------
  1436. ;> edi = pointer to WDATA
  1437. ;------------------------------------------------------------------------------
  1438.         mov     al, [edi + WDATA.fl_wstyle]
  1439.         and     al, 0x0f
  1440.         cmp     al, 0x03
  1441.         jne     @f
  1442.         mov     eax, [_skinh]
  1443.         ret
  1444.     @@: mov     eax, 21
  1445.         ret
  1446.  
  1447. align 4
  1448. ;------------------------------------------------------------------------------
  1449. window._.get_rolledup_height: ;////////////////////////////////////////////////
  1450. ;------------------------------------------------------------------------------
  1451. ;> edi = pointer to WDATA
  1452. ;------------------------------------------------------------------------------
  1453.         mov     al, [edi + WDATA.fl_wstyle]
  1454.         and     al, 0x0f
  1455.         cmp     al, 0x03
  1456.         jb      @f
  1457.         mov     eax, [_skinh]
  1458.         add     eax, 3
  1459.         ret
  1460.     @@: or      al, al
  1461.         jnz     @f
  1462.         mov     eax, 21
  1463.         ret
  1464.     @@: mov     eax, 21 + 2
  1465.         ret
  1466.  
  1467. align 4
  1468. ;------------------------------------------------------------------------------
  1469. window._.set_screen: ;/////////////////////////////////////////////////////////
  1470. ;------------------------------------------------------------------------------
  1471. ;? Reserve window area in screen buffer
  1472. ;------------------------------------------------------------------------------
  1473. ;> eax = left
  1474. ;> ebx = top
  1475. ;> ecx = right
  1476. ;> edx = bottom
  1477. ;> esi = process number
  1478. ;------------------------------------------------------------------------------
  1479. virtual at esp
  1480.   ff_x     dd ?
  1481.   ff_y     dd ?
  1482.   ff_width dd ?
  1483.   ff_xsz   dd ?
  1484.   ff_ysz   dd ?
  1485.   ff_scale dd ?
  1486. end virtual
  1487.  
  1488.         pushad
  1489.  
  1490.         cmp     esi, 1
  1491.         jz      .check_for_shaped_window
  1492.         mov     edi, esi
  1493.         shl     edi, 5
  1494.         cmp     [window_data + edi + WDATA.box.width], 0
  1495.         jnz     .check_for_shaped_window
  1496.         cmp     [window_data + edi + WDATA.box.height], 0
  1497.         jz      .exit
  1498.  
  1499.   .check_for_shaped_window:
  1500.         mov     edi, esi
  1501.         shl     edi, 8
  1502.         add     edi, SLOT_BASE
  1503.         cmp     [edi + APPDATA.wnd_shape], 0
  1504.         jne     .shaped_window
  1505.  
  1506.         ; get x&y size
  1507.         sub     ecx, eax
  1508.         sub     edx, ebx
  1509.         inc     ecx
  1510.         inc     edx
  1511.  
  1512.         ; get WinMap start
  1513.         mov     edi, [Screen_Max_X]
  1514.         inc     edi
  1515.         imul    edi, ebx
  1516.         add     edi, eax
  1517.         add     edi, [_WinMapAddress]
  1518.         mov     eax, esi
  1519.  
  1520.   .next_line:
  1521.         push    ecx
  1522.         rep     stosb
  1523.         pop     ecx
  1524.         add     edi, [Screen_Max_X]
  1525.         inc     edi
  1526.         sub     edi, ecx
  1527.         dec     edx
  1528.         jnz     .next_line
  1529.  
  1530.         jmp     .exit
  1531.  
  1532.   .shaped_window:
  1533.         ;  for (y=0; y <= x_size; y++)
  1534.         ;      for (x=0; x <= x_size; x++)
  1535.         ;          if (shape[coord(x,y,scale)]==1)
  1536.         ;             set_pixel(x, y, process_number);
  1537.  
  1538.         sub     ecx, eax
  1539.         sub     edx, ebx
  1540.         inc     ecx
  1541.         inc     edx
  1542.  
  1543.         push    [edi + APPDATA.wnd_shape_scale]  ; push scale first -> for loop
  1544.  
  1545.         ; get WinMap start  -> ebp
  1546.         push    eax
  1547.         mov     eax, [Screen_Max_X] ; screen_sx
  1548.         inc     eax
  1549.         imul    eax, ebx
  1550.         add     eax, [esp]
  1551.         add     eax, [_WinMapAddress]
  1552.         mov     ebp, eax
  1553.  
  1554.         mov     edi, [edi + APPDATA.wnd_shape]
  1555.         pop     eax
  1556.  
  1557.         ; eax = x_start
  1558.         ; ebx = y_start
  1559.         ; ecx = x_size
  1560.         ; edx = y_size
  1561.         ; esi = process_number
  1562.         ; edi = &shape
  1563.         ;       [scale]
  1564.         push    edx ecx ; for loop - x,y size
  1565.  
  1566.         mov     ecx, esi
  1567.         shl     ecx, 5
  1568.         mov     edx, [window_data + ecx + WDATA.box.top]
  1569.         push    [window_data + ecx + WDATA.box.width]           ; for loop - width
  1570.         mov     ecx, [window_data + ecx + WDATA.box.left]
  1571.         sub     ebx, edx
  1572.         sub     eax, ecx
  1573.         push    ebx eax ; for loop - x,y
  1574.  
  1575.         add     [ff_xsz], eax
  1576.         add     [ff_ysz], ebx
  1577.  
  1578.         mov     ebx, [ff_y]
  1579.  
  1580.   .ff_new_y:
  1581.         mov     edx, [ff_x]
  1582.  
  1583.   .ff_new_x:
  1584.         ; -- body --
  1585.         mov     ecx, [ff_scale]
  1586.         mov     eax, [ff_width]
  1587.         inc     eax
  1588.         shr     eax, cl
  1589.         push    ebx edx
  1590.         shr     ebx, cl
  1591.         shr     edx, cl
  1592.         imul    eax, ebx
  1593.         add     eax, edx
  1594.         pop     edx ebx
  1595.         add     eax, edi
  1596.         call    .read_byte
  1597.         test    al,al
  1598.         jz      @f
  1599.         mov     eax, esi
  1600.         mov     [ebp], al
  1601.         ; -- end body --
  1602.     @@: inc     ebp
  1603.         inc     edx
  1604.         cmp     edx, [ff_xsz]
  1605.         jb      .ff_new_x
  1606.  
  1607.         sub     ebp, [ff_xsz]
  1608.         add     ebp, [ff_x]
  1609.         add     ebp, [Screen_Max_X]  ; screen.x
  1610.         inc     ebp
  1611.         inc     ebx
  1612.         cmp     ebx, [ff_ysz]
  1613.         jb      .ff_new_y
  1614.  
  1615.         add     esp, 24
  1616.  
  1617.   .exit:
  1618.         popad
  1619.         ret
  1620.  
  1621.   .read_byte:
  1622.         ; eax - address
  1623.         ; esi - slot
  1624.         push    eax ecx edx esi
  1625.         xchg    eax, esi
  1626.         lea     ecx, [esp + 12]
  1627.         mov     edx, 1
  1628.         call    read_process_memory
  1629.         pop     esi edx ecx eax
  1630.         ret
  1631.  
  1632. align 4
  1633. ;------------------------------------------------------------------------------
  1634. window._.window_activate: ;////////////////////////////////////////////////////
  1635. ;------------------------------------------------------------------------------
  1636. ;? Activate window
  1637. ;------------------------------------------------------------------------------
  1638. ;> esi = pointer to WIN_POS+ window data
  1639. ;------------------------------------------------------------------------------
  1640.         push    eax ebx
  1641.  
  1642.         ; if type of current active window is 3 or 4, it must be redrawn
  1643.         mov     eax, [TASK_COUNT]
  1644.         movzx   eax, word[WIN_POS + eax * 2]
  1645.         shl     eax, 5
  1646.         add     eax, window_data
  1647.         mov     bl, [eax + WDATA.fl_wstyle]
  1648.         and     bl, 0x0f
  1649.         cmp     bl, 0x03
  1650.         je      .set_window_redraw_flag
  1651.         cmp     bl, 0x04
  1652.         je      .set_window_redraw_flag
  1653.         jmp     .move_others_down
  1654.  
  1655.   .set_window_redraw_flag:
  1656.         mov     [eax + WDATA.fl_redraw], 1
  1657.  
  1658.   .move_others_down:
  1659.         ; ax <- process no
  1660.         movzx   eax, word[esi]
  1661.         ; ax <- position in window stack
  1662.         movzx   eax, word[WIN_STACK + eax * 2]
  1663.  
  1664.         ; drop others
  1665.         xor     ebx, ebx
  1666.  
  1667.   .next_stack_window:
  1668.         cmp     ebx, [TASK_COUNT]
  1669.         jae     .move_self_up
  1670.         inc     ebx
  1671.         cmp     [WIN_STACK + ebx * 2], ax
  1672.         jbe     .next_stack_window
  1673.         dec     word[WIN_STACK + ebx * 2]
  1674.         jmp     .next_stack_window
  1675.  
  1676.   .move_self_up:
  1677.         movzx   eax, word[esi]
  1678.         ; number of processes
  1679.         mov     bx, [TASK_COUNT]
  1680.         ; this is the last (and the upper)
  1681.         mov     [WIN_STACK + eax * 2], bx
  1682.  
  1683.         ; update on screen - window stack
  1684.         xor     ebx, ebx
  1685.  
  1686.   .next_window_pos:
  1687.         cmp     ebx, [TASK_COUNT]
  1688.         jae     .reset_vars
  1689.         inc     ebx
  1690.         movzx   eax, word[WIN_STACK + ebx * 2]
  1691.         mov     [WIN_POS + eax * 2], bx
  1692.         jmp     .next_window_pos
  1693.  
  1694.   .reset_vars:
  1695.         mov     byte[KEY_COUNT], 0
  1696.         mov     byte[BTN_COUNT], 0
  1697.         mov     word[MOUSE_SCROLL_H], 0
  1698.         mov     word[MOUSE_SCROLL_V], 0
  1699.  
  1700.         pop     ebx eax
  1701.         ret
  1702.  
  1703. align 4
  1704. ;------------------------------------------------------------------------------
  1705. window._.check_window_draw: ;//////////////////////////////////////////////////
  1706. ;------------------------------------------------------------------------------
  1707. ;? Check if window is necessary to draw
  1708. ;------------------------------------------------------------------------------
  1709. ;> edi = pointer to WDATA
  1710. ;------------------------------------------------------------------------------
  1711.         mov     cl, [edi + WDATA.fl_wstyle]
  1712.         and     cl, 0x0f
  1713.         cmp     cl, 0x03
  1714.         je      .exit.redraw      ; window type 3
  1715.         cmp     cl, 0x04
  1716.         je      .exit.redraw      ; window type 4
  1717.  
  1718.         push    eax ebx edx esi
  1719.  
  1720.         mov     eax, edi
  1721.         sub     eax, window_data
  1722.         shr     eax, 5
  1723.  
  1724.         ; esi = process number
  1725.  
  1726.         movzx   eax, word[WIN_STACK + eax * 2]  ; get value of the curr process
  1727.         lea     esi, [WIN_POS + eax * 2]        ; get address of this process at 0xC400
  1728.  
  1729.   .next_window:
  1730.         add     esi, 2
  1731.  
  1732.         mov     eax, [TASK_COUNT]
  1733.         lea     eax, word[WIN_POS + eax * 2] ; number of the upper window
  1734.  
  1735.         cmp     esi, eax
  1736.         ja      .exit.no_redraw
  1737.  
  1738.         movzx   edx, word[esi]
  1739.         shl     edx, 5
  1740.         cmp     [CURRENT_TASK + edx + TASKDATA.state], TSTATE_FREE
  1741.         je      .next_window
  1742.  
  1743.         mov     eax, [edi + WDATA.box.top]
  1744.         mov     ebx, [edi + WDATA.box.height]
  1745.         add     ebx, eax
  1746.  
  1747.         mov     ecx, [window_data + edx + WDATA.box.top]
  1748.         cmp     ecx, ebx
  1749.         jge     .next_window
  1750.         add     ecx, [window_data + edx + WDATA.box.height]
  1751.         cmp     eax, ecx
  1752.         jge     .next_window
  1753.  
  1754.         mov     eax, [edi + WDATA.box.left]
  1755.         mov     ebx, [edi + WDATA.box.width]
  1756.         add     ebx, eax
  1757.  
  1758.         mov     ecx, [window_data + edx + WDATA.box.left]
  1759.         cmp     ecx, ebx
  1760.         jge     .next_window
  1761.         add     ecx, [window_data + edx + WDATA.box.width]
  1762.         cmp     eax, ecx
  1763.         jge     .next_window
  1764.  
  1765.         pop     esi edx ebx eax
  1766.  
  1767.   .exit.redraw:
  1768.         xor     ecx, ecx
  1769.         inc     ecx
  1770.         ret
  1771.  
  1772.   .exit.no_redraw:
  1773.         pop     esi edx ebx eax
  1774.         xor     ecx, ecx
  1775.         ret
  1776.  
  1777. align 4
  1778. ;------------------------------------------------------------------------------
  1779. window._.draw_window_frames: ;/////////////////////////////////////////////////
  1780. ;------------------------------------------------------------------------------
  1781. ;? Draw negative window frames
  1782. ;------------------------------------------------------------------------------
  1783. ;> edi = pointer to WDATA
  1784. ;------------------------------------------------------------------------------
  1785.         push    eax
  1786.         cli
  1787.  
  1788.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  1789.         jnz     .exit
  1790.         mov     eax, [new_window_pos.left]
  1791.         cmp     eax, [edi + WDATA.box.left]
  1792.         jnz     .draw
  1793.         mov     eax, [new_window_pos.width]
  1794.         cmp     eax, [edi + WDATA.box.width]
  1795.         jnz     .draw
  1796.         mov     eax, [new_window_pos.top]
  1797.         cmp     eax, [edi + WDATA.box.top]
  1798.         jnz     .draw
  1799.         mov     eax, [new_window_pos.height]
  1800.         cmp     eax, [edi + WDATA.box.height]
  1801.         jnz     .draw
  1802.         xor     [edi + WDATA.fl_wdrawn], 2
  1803.  
  1804.   .draw:
  1805.         push    ebx esi
  1806.         mov     eax, [new_window_pos.left - 2]
  1807.         mov     ax, word[new_window_pos.left]
  1808.         add     ax, word[new_window_pos.width]
  1809.         mov     ebx, [new_window_pos.top - 2]
  1810.         mov     bx, word[new_window_pos.top]
  1811.         add     bx, word[new_window_pos.height]
  1812.         mov     esi, 0x01000000
  1813.         call    draw_rectangle.forced
  1814.         pop     esi ebx
  1815.  
  1816.   .exit:
  1817.         sti
  1818.         pop     eax
  1819.         ret
  1820.  
  1821.   .forced:
  1822.         push    eax
  1823.         cli
  1824.         jmp     .draw
  1825.