Subversion Repositories Kolibri OS

Rev

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

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