Subversion Repositories Kolibri OS

Rev

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