Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2010-2012. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. $Revision: 3555 $
  9.  
  10. include 'mousepointer.inc'
  11.  
  12. ;==============================================================================
  13. ;///// public functions ///////////////////////////////////////////////////////
  14. ;==============================================================================
  15.  
  16. mouse.LEFT_BUTTON_FLAG   = 0001b
  17. mouse.RIGHT_BUTTON_FLAG  = 0010b
  18. mouse.MIDDLE_BUTTON_FLAG = 0100b
  19.  
  20. mouse.BUTTONS_MASK = \
  21.   mouse.LEFT_BUTTON_FLAG or \
  22.   mouse.RIGHT_BUTTON_FLAG or \
  23.   mouse.MIDDLE_BUTTON_FLAG
  24.  
  25. mouse.WINDOW_RESIZE_N_FLAG = 000001b
  26. mouse.WINDOW_RESIZE_W_FLAG = 000010b
  27. mouse.WINDOW_RESIZE_S_FLAG = 000100b
  28. mouse.WINDOW_RESIZE_E_FLAG = 001000b
  29. mouse.WINDOW_MOVE_FLAG     = 010000b
  30.  
  31. mouse.WINDOW_RESIZE_SW_FLAG = \
  32.   mouse.WINDOW_RESIZE_S_FLAG or \
  33.   mouse.WINDOW_RESIZE_W_FLAG
  34. mouse.WINDOW_RESIZE_SE_FLAG = \
  35.   mouse.WINDOW_RESIZE_S_FLAG or \
  36.   mouse.WINDOW_RESIZE_E_FLAG
  37.  
  38. align 4
  39. ;------------------------------------------------------------------------------
  40. mouse_check_events: ;//////////////////////////////////////////////////////////
  41. ;------------------------------------------------------------------------------
  42. ;? Check if mouse buttons state or cursor position has changed and call
  43. ;? appropriate handlers
  44. ;------------------------------------------------------------------------------
  45.         push    eax ebx
  46.  
  47.         mov     al, [BTN_DOWN]
  48.         mov     bl, [mouse.state.buttons]
  49.         and     al, mouse.BUTTONS_MASK
  50.         mov     cl, al
  51.         xchg    cl, [mouse.state.buttons]
  52.         xor     bl, al
  53.         push    eax ebx
  54.  
  55.         ; did any mouse button changed its state?
  56.         or      bl, bl
  57.         jz      .check_position
  58.  
  59.         ; yes it did, is that the first button of all pressed down?
  60.         or      cl, cl
  61.         jnz     .check_buttons_released
  62.  
  63.         ; yes it is, activate window user is pointing at, if needed
  64.         call    mouse._.activate_sys_window_under_cursor
  65.  
  66.         ; NOTE: this code wouldn't be necessary if we knew window did
  67.         ;       already redraw itself after call above
  68.         or      eax, eax
  69.         jnz     .exit
  70.  
  71.         ; is there any system button under cursor?
  72.         call    mouse._.find_sys_button_under_cursor
  73.         or      eax, eax
  74.         jz      .check_buttons_released
  75.  
  76.         ; yes there is, activate it and exit
  77.         mov     [mouse.active_sys_button.pbid], eax
  78.         mov     [mouse.active_sys_button.coord], ebx
  79.         mov     cl, [mouse.state.buttons]
  80.         mov     [mouse.active_sys_button.buttons], cl
  81.         call    sys_button_activate_handler
  82.         jmp     .exit
  83.  
  84.   .check_buttons_released:
  85.         cmp     [mouse.state.buttons], 0
  86.         jnz     .buttons_changed
  87.  
  88.         ; did we press some button earlier?
  89.         cmp     [mouse.active_sys_button.pbid], 0
  90.         je      .buttons_changed
  91.  
  92.         ; yes we did, deactivate it
  93.         xor     eax, eax
  94.         xchg    eax, [mouse.active_sys_button.pbid]
  95.         mov     ebx, [mouse.active_sys_button.coord]
  96.         mov     cl, [mouse.active_sys_button.buttons]
  97.         push    eax ebx
  98.         call    sys_button_deactivate_handler
  99.         pop     edx ecx
  100.  
  101.         ; is the button under cursor the one we deactivated?
  102.         call    mouse._.find_sys_button_under_cursor
  103.         cmp     eax, ecx
  104.         jne     .exit
  105.         cmp     ebx, edx
  106.         jne     .exit
  107.  
  108.         ; yes it is, perform associated action
  109.         mov     cl, [mouse.active_sys_button.buttons]
  110.         call    sys_button_perform_handler
  111.         jmp     .exit
  112.  
  113.   .buttons_changed:
  114.         test    byte[esp], mouse.LEFT_BUTTON_FLAG
  115.         jz      @f
  116.         mov     eax, [esp + 4]
  117.         call    .call_left_button_handler
  118.  
  119.     @@:
  120.         test    byte[esp], mouse.RIGHT_BUTTON_FLAG
  121.         jz      @f
  122.         mov     eax, [esp + 4]
  123.         call    .call_right_button_handler
  124.  
  125.     @@:
  126.         test    byte[esp], mouse.MIDDLE_BUTTON_FLAG
  127.         jz      .check_position
  128.         mov     eax, [esp + 4]
  129.         call    .call_middle_button_handler
  130.  
  131.   .check_position:
  132.         movzx   eax, word[MOUSE_X]
  133.         movzx   ebx, word[MOUSE_Y]
  134.         cmp     eax, [mouse.state.pos.x]
  135.         jne     .position_changed
  136.         cmp     ebx, [mouse.state.pos.y]
  137.         je      .exit
  138.  
  139.   .position_changed:
  140.         xchg    eax, [mouse.state.pos.x]
  141.         xchg    ebx, [mouse.state.pos.y]
  142.  
  143.         call    mouse._.move_handler
  144.  
  145.   .exit:
  146.         add     esp, 8
  147.         pop     ebx eax
  148.         ret
  149.  
  150.   .call_left_button_handler:
  151.         test    eax, mouse.LEFT_BUTTON_FLAG
  152.         jnz     mouse._.left_button_press_handler
  153.         jmp     mouse._.left_button_release_handler
  154.  
  155.   .call_right_button_handler:
  156.         test    eax, mouse.RIGHT_BUTTON_FLAG
  157.         jnz     mouse._.right_button_press_handler
  158.         jmp     mouse._.right_button_release_handler
  159.  
  160.   .call_middle_button_handler:
  161.         test    eax, mouse.MIDDLE_BUTTON_FLAG
  162.         jnz     mouse._.middle_button_press_handler
  163.         jmp     mouse._.middle_button_release_handler
  164.  
  165. ;==============================================================================
  166. ;///// private functions //////////////////////////////////////////////////////
  167. ;==============================================================================
  168.  
  169. uglobal
  170.   mouse.state:
  171.     .pos     POINT
  172.     .buttons db ?
  173.  
  174.   ; NOTE: since there's no unique and lifetime-constant button identifiers,
  175.   ;       we're using two dwords to identify each of them:
  176.   ;       * pbid - process slot (high 8 bits) and button id (low 24 bits) pack
  177.   ;       * coord - left (high 16 bits) and top (low 16 bits) coordinates pack
  178.   align 4
  179.   mouse.active_sys_button:
  180.     .pbid    dd ?
  181.     .coord   dd ?
  182.     .buttons db ?
  183.  
  184.   align 4
  185.   mouse.active_sys_window:
  186.     .pslot      dd ?
  187.     .old_box    BOX
  188.     .new_box    BOX
  189.     .delta      POINT
  190.     .last_ticks dd ?
  191.     .action     db ?
  192. endg
  193.  
  194. align 4
  195. ;------------------------------------------------------------------------------
  196. mouse._.left_button_press_handler: ;///////////////////////////////////////////
  197. ;------------------------------------------------------------------------------
  198. ;? Called when left mouse button has been pressed down
  199. ;------------------------------------------------------------------------------
  200.         test    [mouse.state.buttons], not mouse.LEFT_BUTTON_FLAG
  201.         jnz     .exit
  202.  
  203.         call    mouse._.find_sys_window_under_cursor
  204.         call    mouse._.check_sys_window_actions
  205.         mov     [mouse.active_sys_window.action], al
  206.         or      eax, eax
  207.         jz      .exit
  208.  
  209.         xchg    eax, edx
  210.         test    dl, mouse.WINDOW_MOVE_FLAG
  211.         jz      @f
  212.  
  213.         mov     eax, [timer_ticks]
  214.         mov     ebx, eax
  215.         xchg    ebx, [mouse.active_sys_window.last_ticks]
  216.         sub     eax, ebx
  217.         cmp     eax, 50
  218.         jg      @f
  219.  
  220.         mov     [mouse.active_sys_window.last_ticks], 0
  221.         call    sys_window_maximize_handler
  222.         jmp     .exit
  223.  
  224.     @@:
  225.         test    [edi + WDATA.fl_wstate], WSTATE_MAXIMIZED
  226.         jnz     .exit
  227.         mov     [mouse.active_sys_window.pslot], esi
  228.         lea     eax, [edi + WDATA.box]
  229.         mov     ebx, mouse.active_sys_window.old_box
  230.         mov     ecx, sizeof.BOX
  231.         call    memmove
  232.         mov     ebx, mouse.active_sys_window.new_box
  233.         call    memmove
  234.         test    edx, mouse.WINDOW_MOVE_FLAG
  235.         jz      @f
  236.  
  237.         call    .calculate_n_delta
  238.         call    .calculate_w_delta
  239.         jmp     .call_window_handler
  240.  
  241.     @@:
  242.         test    dl, mouse.WINDOW_RESIZE_W_FLAG
  243.         jz      @f
  244.         call    .calculate_w_delta
  245.  
  246.     @@:
  247.         test    dl, mouse.WINDOW_RESIZE_S_FLAG
  248.         jz      @f
  249.         call    .calculate_s_delta
  250.  
  251.     @@:
  252.         test    dl, mouse.WINDOW_RESIZE_E_FLAG
  253.         jz      .call_window_handler
  254.         call    .calculate_e_delta
  255.  
  256.   .call_window_handler:
  257. ;        mov     eax, mouse.active_sys_window.old_box
  258. ;        call    sys_window_start_moving_handler
  259.  
  260.   .exit:
  261.         ret
  262.  
  263.   .calculate_n_delta:
  264.         mov     eax, [mouse.state.pos.y]
  265.         sub     eax, [mouse.active_sys_window.old_box.top]
  266.         mov     [mouse.active_sys_window.delta.y], eax
  267.         ret
  268.  
  269.   .calculate_w_delta:
  270.         mov     eax, [mouse.state.pos.x]
  271.         sub     eax, [mouse.active_sys_window.old_box.left]
  272.         mov     [mouse.active_sys_window.delta.x], eax
  273.         ret
  274.  
  275.   .calculate_s_delta:
  276.         mov     eax, [mouse.active_sys_window.old_box.top]
  277.         add     eax, [mouse.active_sys_window.old_box.height]
  278.         sub     eax, [mouse.state.pos.y]
  279.         mov     [mouse.active_sys_window.delta.y], eax
  280.         ret
  281.  
  282.   .calculate_e_delta:
  283.         mov     eax, [mouse.active_sys_window.old_box.left]
  284.         add     eax, [mouse.active_sys_window.old_box.width]
  285.         sub     eax, [mouse.state.pos.x]
  286.         mov     [mouse.active_sys_window.delta.x], eax
  287.         ret
  288.  
  289. align 4
  290. ;------------------------------------------------------------------------------
  291. mouse._.left_button_release_handler: ;/////////////////////////////////////////
  292. ;------------------------------------------------------------------------------
  293. ;? Called when left mouse button has been released
  294. ;------------------------------------------------------------------------------
  295.         xor     esi, esi
  296.         xchg    esi, [mouse.active_sys_window.pslot]
  297.         or      esi, esi
  298.         jz      .exit
  299.  
  300.         mov     eax, esi
  301.         shl     eax, 5
  302.         add     eax, window_data + WDATA.box
  303.         mov     ebx, mouse.active_sys_window.old_box
  304.         mov     ecx, sizeof.BOX
  305.         call    memmove
  306.  
  307.         mov     eax, mouse.active_sys_window.old_box
  308.         mov     ebx, mouse.active_sys_window.new_box
  309.         call    sys_window_end_moving_handler
  310.  
  311.   .exit:
  312.         and     [mouse.active_sys_window.action], 0
  313.         ret
  314.  
  315. align 4
  316. ;------------------------------------------------------------------------------
  317. mouse._.right_button_press_handler: ;//////////////////////////////////////////
  318. ;------------------------------------------------------------------------------
  319. ;? Called when right mouse button has been pressed down
  320. ;------------------------------------------------------------------------------
  321.         test    [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG
  322.         jnz     .exit
  323.  
  324.         call    mouse._.find_sys_window_under_cursor
  325.         call    mouse._.check_sys_window_actions
  326.         test    al, mouse.WINDOW_MOVE_FLAG
  327.         jz      .exit
  328.  
  329.         call    sys_window_rollup_handler
  330.  
  331.   .exit:
  332.         ret
  333.  
  334. align 4
  335. ;------------------------------------------------------------------------------
  336. mouse._.right_button_release_handler: ;////////////////////////////////////////
  337. ;------------------------------------------------------------------------------
  338. ;? Called when right mouse button has been released
  339. ;------------------------------------------------------------------------------
  340.         ret
  341.  
  342. align 4
  343. ;------------------------------------------------------------------------------
  344. mouse._.middle_button_press_handler: ;/////////////////////////////////////////
  345. ;------------------------------------------------------------------------------
  346. ;? Called when middle mouse button has been pressed down
  347. ;------------------------------------------------------------------------------
  348.         ret
  349.  
  350. align 4
  351. ;------------------------------------------------------------------------------
  352. mouse._.middle_button_release_handler: ;///////////////////////////////////////
  353. ;------------------------------------------------------------------------------
  354. ;? Called when middle mouse button has been released
  355. ;------------------------------------------------------------------------------
  356.         ret
  357.  
  358. align 4
  359. ;------------------------------------------------------------------------------
  360. mouse._.move_handler: ;////////////////////////////////////////////////////////
  361. ;------------------------------------------------------------------------------
  362. ;? Called when cursor has been moved
  363. ;------------------------------------------------------------------------------
  364. ;> eax = old x coord
  365. ;> ebx = old y coord
  366. ;------------------------------------------------------------------------------
  367.         cmp     [mouse.active_sys_button.pbid], 0
  368.         jnz     .exit
  369.  
  370.         mov     esi, [mouse.active_sys_window.pslot]
  371.         or      esi, esi
  372.         jz      .exit
  373.  
  374.         mov     eax, mouse.active_sys_window.new_box
  375.         mov     ebx, mouse.active_sys_window.old_box
  376.         mov     ecx, sizeof.BOX
  377.         call    memmove
  378.  
  379.         mov     dl, [mouse.active_sys_window.action]
  380.         test    dl, mouse.WINDOW_MOVE_FLAG
  381.         jz      .check_resize_w
  382.  
  383.         mov     eax, [mouse.state.pos.x]
  384.         sub     eax, [mouse.active_sys_window.delta.x]
  385.         mov     [mouse.active_sys_window.new_box.left], eax
  386.         mov     eax, [mouse.state.pos.y]
  387.         sub     eax, [mouse.active_sys_window.delta.y]
  388.         mov     [mouse.active_sys_window.new_box.top], eax
  389.  
  390.         mov     eax, [mouse.active_sys_window.new_box.left]
  391.         or      eax, eax
  392.         jge     @f
  393.         xor     eax, eax
  394.         mov     [mouse.active_sys_window.new_box.left], eax
  395.     @@:
  396.         add     eax, [mouse.active_sys_window.new_box.width]
  397.         cmp     eax, [Screen_Max_X]
  398.         jl      @f
  399.         sub     eax, [Screen_Max_X]
  400.         sub     [mouse.active_sys_window.new_box.left], eax
  401.     @@:
  402.         mov     eax, [mouse.active_sys_window.new_box.top]
  403.         or      eax, eax
  404.         jge     @f
  405.         xor     eax, eax
  406.         mov     [mouse.active_sys_window.new_box.top], eax
  407.     @@:
  408.         add     eax, [mouse.active_sys_window.new_box.height]
  409.         cmp     eax, [Screen_Max_Y]
  410.         jle     .call_window_handler
  411.         sub     eax, [Screen_Max_Y]
  412.         sub     [mouse.active_sys_window.new_box.top], eax
  413.         jmp     .call_window_handler
  414.  
  415.   .check_resize_w:
  416.         test    dl, mouse.WINDOW_RESIZE_W_FLAG
  417.         jz      .check_resize_s
  418.  
  419.         mov     eax, [mouse.state.pos.x]
  420.         sub     eax, [mouse.active_sys_window.delta.x]
  421.         mov     [mouse.active_sys_window.new_box.left], eax
  422.         sub     eax, [mouse.active_sys_window.old_box.left]
  423.         sub     [mouse.active_sys_window.new_box.width], eax
  424.  
  425.         mov     eax, [mouse.active_sys_window.new_box.width]
  426.         sub     eax, 127
  427.         jge     @f
  428.         add     [mouse.active_sys_window.new_box.left], eax
  429.         mov     [mouse.active_sys_window.new_box.width], 127
  430.     @@:
  431.         mov     eax, [mouse.active_sys_window.new_box.left]
  432.         or      eax, eax
  433.         jge     .check_resize_s
  434.         add     [mouse.active_sys_window.new_box.width], eax
  435.         xor     eax, eax
  436.         mov     [mouse.active_sys_window.new_box.left], eax
  437.  
  438.   .check_resize_s:
  439.         test    dl, mouse.WINDOW_RESIZE_S_FLAG
  440.         jz      .check_resize_e
  441.  
  442.         mov     eax, [mouse.state.pos.y]
  443.         add     eax, [mouse.active_sys_window.delta.y]
  444.         sub     eax, [mouse.active_sys_window.old_box.top]
  445.         mov     [mouse.active_sys_window.new_box.height], eax
  446.  
  447.         push    eax
  448.         mov     edi, esi
  449.         shl     edi, 5
  450.         add     edi, window_data
  451.         call    window._.get_rolledup_height
  452.         mov     ecx, eax
  453.         pop     eax
  454.         mov     eax, [mouse.active_sys_window.new_box.height]
  455.         cmp     eax, ecx
  456.         jge     @f
  457.         mov     eax, ecx
  458.         mov     [mouse.active_sys_window.new_box.height], eax
  459.     @@:
  460.         add     eax, [mouse.active_sys_window.new_box.top]
  461.         cmp     eax, [Screen_Max_Y]
  462.         jle     .check_resize_e
  463.         sub     eax, [Screen_Max_Y]
  464.         neg     eax
  465.         add     [mouse.active_sys_window.new_box.height], eax
  466.         mov     ecx, [Screen_Max_Y]
  467.         cmp     ecx, eax
  468.         jge     .check_resize_e
  469.         mov     [mouse.active_sys_window.new_box.height], ecx
  470.  
  471.   .check_resize_e:
  472.         test    dl, mouse.WINDOW_RESIZE_E_FLAG
  473.         jz      .call_window_handler
  474.  
  475.         mov     eax, [mouse.state.pos.x]
  476.         add     eax, [mouse.active_sys_window.delta.x]
  477.         sub     eax, [mouse.active_sys_window.old_box.left]
  478.         mov     [mouse.active_sys_window.new_box.width], eax
  479.  
  480.         mov     eax, [mouse.active_sys_window.new_box.width]
  481.         cmp     eax, 127
  482.         jge     @f
  483.         mov     eax, 127
  484.         mov     [mouse.active_sys_window.new_box.width], eax
  485.     @@:
  486.         add     eax, [mouse.active_sys_window.new_box.left]
  487.         cmp     eax, [Screen_Max_X]
  488.         jle     .call_window_handler
  489.         sub     eax, [Screen_Max_X]
  490.         neg     eax
  491.         add     [mouse.active_sys_window.new_box.width], eax
  492.         mov     ecx, [Screen_Max_X]
  493.         cmp     ecx, eax
  494.         jge     .call_window_handler
  495.         mov     [mouse.active_sys_window.new_box.width], ecx
  496.  
  497.   .call_window_handler:
  498.         mov     eax, mouse.active_sys_window.old_box
  499.         mov     ebx, mouse.active_sys_window.new_box
  500.  
  501.         push    esi
  502.         mov     esi, mouse.active_sys_window.old_box
  503.         mov     edi, mouse.active_sys_window.new_box
  504.         mov     ecx, sizeof.BOX / 4
  505.         repe
  506.         cmpsd
  507.         pop     esi
  508.         je      .exit
  509.  
  510.         mov     [mouse.active_sys_window.last_ticks], 0
  511.         call    sys_window_moving_handler
  512.  
  513.   .exit:
  514.         ret
  515.  
  516. align 4
  517. ;------------------------------------------------------------------------------
  518. mouse._.find_sys_window_under_cursor: ;////////////////////////////////////////
  519. ;------------------------------------------------------------------------------
  520. ;? Find system window object which is currently visible on screen and has
  521. ;? mouse cursor within its bounds
  522. ;------------------------------------------------------------------------------
  523. ;< esi = process slot
  524. ;< edi = pointer to WDATA struct
  525. ;------------------------------------------------------------------------------
  526. ;        mov     esi, [Screen_Max_X]
  527. ;        inc     esi
  528. ;        imul    esi, [mouse.state.pos.y]
  529.         mov     esi, [mouse.state.pos.y]
  530.         mov     esi, [d_width_calc_area + esi*4]
  531.  
  532.         add     esi, [_WinMapAddress]
  533.         add     esi, [mouse.state.pos.x]
  534.         movzx   esi, byte[esi]
  535.         mov     edi, esi
  536.         shl     edi, 5
  537.         add     edi, window_data
  538.         ret
  539.  
  540. align 4
  541. ;------------------------------------------------------------------------------
  542. mouse._.activate_sys_window_under_cursor: ;////////////////////////////////////
  543. ;------------------------------------------------------------------------------
  544. ;? <description>
  545. ;------------------------------------------------------------------------------
  546.         ; activate and redraw window under cursor (if necessary)
  547.         call    mouse._.find_sys_window_under_cursor
  548.         movzx   esi, word[WIN_STACK + esi * 2]
  549.         lea     esi, [WIN_POS + esi * 2]
  550.         jmp     waredraw
  551.  
  552. align 4
  553. ;------------------------------------------------------------------------------
  554. mouse._.find_sys_button_under_cursor: ;////////////////////////////////////////
  555. ;------------------------------------------------------------------------------
  556. ;? Find system button object which is currently visible on screen and has
  557. ;? mouse cursor within its bounds
  558. ;------------------------------------------------------------------------------
  559. ;< eax = pack[8(process slot), 24(button id)] or 0
  560. ;< ebx = pack[16(button x coord), 16(button y coord)]
  561. ;------------------------------------------------------------------------------
  562.         push    ecx edx esi edi
  563.  
  564.         call    mouse._.find_sys_window_under_cursor
  565.         mov     edx, esi
  566.  
  567.         ; check if any process button contains cursor
  568.         mov     eax, [BTN_ADDR]
  569.         mov     ecx, [eax]
  570.         imul    esi, ecx, sizeof.SYS_BUTTON
  571.         add     esi, eax
  572.         inc     ecx
  573.         add     esi, sizeof.SYS_BUTTON
  574.  
  575.   .next_button:
  576.         dec     ecx
  577.         jz      .not_found
  578.  
  579.         add     esi, -sizeof.SYS_BUTTON
  580.  
  581.         ; does it belong to our process?
  582.         cmp     dx, [esi + SYS_BUTTON.pslot]
  583.         jne     .next_button
  584.  
  585.         ; does it contain cursor coordinates?
  586.         mov     eax, [mouse.state.pos.x]
  587.         sub     eax, [edi + WDATA.box.left]
  588.         sub     ax, [esi + SYS_BUTTON.left]
  589.         jl      .next_button
  590.         sub     ax, [esi + SYS_BUTTON.width]
  591.         jge     .next_button
  592.         mov     eax, [mouse.state.pos.y]
  593.         sub     eax, [edi + WDATA.box.top]
  594.         sub     ax, [esi + SYS_BUTTON.top]
  595.         jl      .next_button
  596.         sub     ax, [esi + SYS_BUTTON.height]
  597.         jge     .next_button
  598.  
  599.         ; okay, return it
  600.         shl     edx, 24
  601.         mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
  602.         mov     ax, [esi + SYS_BUTTON.id_lo]
  603.         and     eax, 0x0ffffff
  604.         or      eax, edx
  605.         mov     ebx, dword[esi + SYS_BUTTON.left - 2]
  606.         mov     bx, [esi + SYS_BUTTON.top]
  607.         jmp     .exit
  608.  
  609.   .not_found:
  610.         xor     eax, eax
  611.         xor     ebx, ebx
  612.  
  613.   .exit:
  614.         pop     edi esi edx ecx
  615.         ret
  616.  
  617. align 4
  618. ;------------------------------------------------------------------------------
  619. mouse._.check_sys_window_actions: ;////////////////////////////////////////////
  620. ;------------------------------------------------------------------------------
  621. ;? <description>
  622. ;------------------------------------------------------------------------------
  623. ;< eax = action flags or 0
  624. ;------------------------------------------------------------------------------
  625.         ; is window movable?
  626.         test    byte[edi + WDATA.cl_titlebar + 3], 0x01
  627.         jnz     .no_action
  628.  
  629.         mov     eax, [mouse.state.pos.x]
  630.         mov     ebx, [mouse.state.pos.y]
  631.         sub     eax, [edi + WDATA.box.left]
  632.         sub     ebx, [edi + WDATA.box.top]
  633.  
  634.         ; is there a window titlebar under cursor?
  635.         push    eax
  636.         call    window._.get_titlebar_height
  637.         cmp     ebx, eax
  638.         pop     eax
  639.         jl      .move_action
  640.  
  641.         ; no there isn't, can it be resized then?
  642.         mov     dl, [edi + WDATA.fl_wstyle]
  643.         and     dl, 0x0f
  644.         ; NOTE: dangerous optimization, revise if window types changed;
  645.         ;       this currently implies only types 2 and 3 could be resized
  646.         test    dl, 2
  647.         jz      .no_action
  648.  
  649.         mov     ecx, [edi + WDATA.box.width]
  650.         add     ecx, -window.BORDER_SIZE
  651.         mov     edx, [edi + WDATA.box.height]
  652.         add     edx, -window.BORDER_SIZE
  653.  
  654.         ; is it rolled up?
  655.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  656.         jnz     .resize_w_or_e_action
  657.  
  658.         cmp     eax, window.BORDER_SIZE
  659.         jl      .resize_w_action
  660.         cmp     eax, ecx
  661.         jg      .resize_e_action
  662.         cmp     ebx, edx
  663.         jle     .no_action
  664.  
  665.   .resize_s_action:
  666.         cmp     eax, window.BORDER_SIZE + 10
  667.         jl      .resize_sw_action
  668.         add     ecx, -10
  669.         cmp     eax, ecx
  670.         jge     .resize_se_action
  671.         mov     eax, mouse.WINDOW_RESIZE_S_FLAG
  672.         jmp     .exit
  673.  
  674.   .resize_w_or_e_action:
  675.         cmp     eax, window.BORDER_SIZE + 10
  676.         jl      .resize_w_action.direct
  677.         add     ecx, -10
  678.         cmp     eax, ecx
  679.         jg      .resize_e_action.direct
  680.         jmp     .no_action
  681.  
  682.   .resize_w_action:
  683.         add     edx, -10
  684.         cmp     ebx, edx
  685.         jge     .resize_sw_action
  686.   .resize_w_action.direct:
  687.         mov     eax, mouse.WINDOW_RESIZE_W_FLAG
  688.         jmp     .exit
  689.  
  690.   .resize_e_action:
  691.         add     edx, -10
  692.         cmp     ebx, edx
  693.         jge     .resize_se_action
  694.   .resize_e_action.direct:
  695.         mov     eax, mouse.WINDOW_RESIZE_E_FLAG
  696.         jmp     .exit
  697.  
  698.   .resize_sw_action:
  699.         mov     eax, mouse.WINDOW_RESIZE_SW_FLAG
  700.         jmp     .exit
  701.  
  702.   .resize_se_action:
  703.         mov     eax, mouse.WINDOW_RESIZE_SE_FLAG
  704.         jmp     .exit
  705.  
  706.   .move_action:
  707.         mov     eax, mouse.WINDOW_MOVE_FLAG
  708.         jmp     .exit
  709.  
  710.   .no_action:
  711.         xor     eax, eax
  712.  
  713.   .exit:
  714.         ret
  715.