Subversion Repositories Kolibri OS

Rev

Rev 1930 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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