Subversion Repositories Kolibri OS

Rev

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

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