Subversion Repositories Kolibri OS

Rev

Rev 9848 | Rev 9926 | 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: 9850 $
  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.         ; is there any system button under cursor?
  63.         call    mouse._.find_sys_button_under_cursor
  64.         or      eax, eax
  65.         jz      .check_buttons_released
  66.  
  67.         ; yes there is, activate it and exit
  68.         mov     [mouse.active_sys_button.pbid], eax
  69.         mov     [mouse.active_sys_button.coord], ebx
  70.         mov     cl, [mouse.state.buttons]
  71.         mov     [mouse.active_sys_button.buttons], cl
  72.         call    sys_button_activate_handler
  73.         jmp     .exit
  74.  
  75.   .check_buttons_released:
  76.         cmp     [mouse.state.buttons], 0
  77.         jnz     .buttons_changed
  78.  
  79.         ; did we press some button earlier?
  80.         cmp     [mouse.active_sys_button.pbid], 0
  81.         je      .buttons_changed
  82.  
  83.         ; yes we did, deactivate it
  84.         xor     eax, eax
  85.         xchg    eax, [mouse.active_sys_button.pbid]
  86.         mov     ebx, [mouse.active_sys_button.coord]
  87.         mov     cl, [mouse.active_sys_button.buttons]
  88.         push    eax ebx
  89.         call    sys_button_deactivate_handler
  90.         pop     edx ecx
  91.  
  92.         ; is the button under cursor the one we deactivated?
  93.         call    mouse._.find_sys_button_under_cursor
  94.         cmp     eax, ecx
  95.         jne     .exit
  96.         cmp     ebx, edx
  97.         jne     .exit
  98.  
  99.         ; yes it is, perform associated action
  100.         mov     cl, [mouse.active_sys_button.buttons]
  101.         call    sys_button_perform_handler
  102.         jmp     .exit
  103.  
  104.   .buttons_changed:
  105.         test    byte[esp], mouse.LEFT_BUTTON_FLAG
  106.         jz      @f
  107.         mov     eax, [esp + 4]
  108.         call    .call_left_button_handler
  109.  
  110.     @@:
  111.         test    byte[esp], mouse.RIGHT_BUTTON_FLAG
  112.         jz      @f
  113.         mov     eax, [esp + 4]
  114.         call    .call_right_button_handler
  115.  
  116.     @@:
  117.         test    byte[esp], mouse.MIDDLE_BUTTON_FLAG
  118.         jz      .check_position
  119.         mov     eax, [esp + 4]
  120.         call    .call_middle_button_handler
  121.  
  122.   .check_position:
  123.         movzx   eax, word[MOUSE_X]
  124.         movzx   ebx, word[MOUSE_Y]
  125.         cmp     eax, [mouse.state.pos.x]
  126.         jne     .position_changed
  127.         cmp     ebx, [mouse.state.pos.y]
  128.         je      .exit
  129.  
  130.   .position_changed:
  131.         xchg    eax, [mouse.state.pos.x]
  132.         xchg    ebx, [mouse.state.pos.y]
  133.  
  134.         call    mouse._.move_handler
  135.  
  136.   .exit:
  137.         add     esp, 8
  138.         pop     ebx eax
  139.         ret
  140.  
  141.   .call_left_button_handler:
  142.         test    eax, mouse.LEFT_BUTTON_FLAG
  143.         jnz     mouse._.left_button_press_handler
  144.         jmp     mouse._.left_button_release_handler
  145.  
  146.   .call_right_button_handler:
  147.         test    eax, mouse.RIGHT_BUTTON_FLAG
  148.         jnz     mouse._.right_button_press_handler
  149.         jmp     mouse._.right_button_release_handler
  150.  
  151.   .call_middle_button_handler:
  152.         test    eax, mouse.MIDDLE_BUTTON_FLAG
  153.         jnz     mouse._.middle_button_press_handler
  154.         jmp     mouse._.middle_button_release_handler
  155.  
  156. ;===============================
  157. ;////// private functions //////
  158. ;===============================
  159.  
  160. uglobal
  161.   mouse.state:
  162.     .pos     POINT
  163.     .buttons db ?
  164.  
  165. ; NOTE: since there's no unique and lifetime-constant button identifiers,
  166. ; we are using two dwords to identify each of them:
  167. ;   * pbid - process slot (high 8 bits) and button id (low 24 bits) pack
  168. ;   * coord - left (high 16 bits) and top (low 16 bits) coordinates pack
  169.   align 4
  170.   mouse.active_sys_button:
  171.     .pbid    dd ?
  172.     .coord   dd ?
  173.     .buttons db ?
  174.  
  175.   align 4
  176.   mouse.active_sys_window:
  177.     .pslot      dd ?
  178.     .old_box    BOX
  179.     .new_box    BOX
  180.     .delta      POINT
  181.     .last_ticks dd ?
  182.     .action     db ?
  183. endg
  184.  
  185. iglobal
  186.         fl_moving db 0
  187.         rb 3
  188. endg
  189.  
  190. align 4
  191. ;-----------------------------------------------------------------
  192. mouse._.left_button_press_handler:
  193. ; Called when left mouse button has been pressed down
  194.         bts     word [BTN_DOWN], 8
  195.         mov     eax, [timer_ticks]
  196.         mov     ebx, eax
  197.         xchg    ebx, [mouse.active_sys_window.last_ticks]
  198.         sub     eax, ebx
  199.         movzx   ebx, [mouse_doubleclick_delay]
  200.         cmp     eax, ebx
  201.         jg      @f
  202.         bts     dword [BTN_DOWN], 24
  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.         bt      dword [BTN_DOWN], 24
  218.         jnc     @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.   .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. ; Called when left mouse button has been released
  290.         bts     dword [BTN_DOWN], 16
  291.         xor     esi, esi
  292.         xchg    esi, [mouse.active_sys_window.pslot]
  293.         or      esi, esi
  294.         jz      .exit
  295.  
  296.         mov     eax, esi
  297.         shl     eax, 5
  298.         add     eax, window_data + WDATA.box
  299.         mov     ebx, mouse.active_sys_window.old_box
  300.         mov     ecx, sizeof.BOX
  301.         call    memmove
  302.  
  303.         mov     eax, mouse.active_sys_window.old_box
  304.         mov     ebx, mouse.active_sys_window.new_box
  305.         call    sys_window_end_moving_handler
  306.  
  307.   .exit:
  308.         and     [mouse.active_sys_window.action], 0
  309.         mov     [fl_moving], 0
  310.         ret
  311.  
  312. mouse._.right_button_press_handler:
  313.         bts     word [BTN_DOWN], 9
  314.         test    [mouse.state.buttons], not mouse.RIGHT_BUTTON_FLAG
  315.         jnz     @f
  316.         call    mouse._.find_sys_window_under_cursor
  317.         call    mouse._.check_sys_window_actions
  318.         test    al, mouse.WINDOW_MOVE_FLAG
  319.         jz      @f
  320.         jmp     sys_window_rollup_handler
  321.  
  322. mouse._.right_button_release_handler:
  323.         bts     dword [BTN_DOWN], 17
  324. @@:
  325.         ret
  326.  
  327. mouse._.middle_button_press_handler:
  328.         bts     word [BTN_DOWN], 10
  329.         ret
  330.  
  331. mouse._.middle_button_release_handler:
  332.         bts     dword [BTN_DOWN], 18
  333.         ret
  334.  
  335. align 4
  336. ;-----------------------------------------------------------------
  337. mouse._.move_handler:
  338. ; Called when cursor has been moved
  339. ;> eax = old x coord
  340. ;> ebx = old y coord
  341.         push    eax ebx
  342.  
  343.         call    mouse._.find_sys_window_under_cursor
  344.         call    mouse._.check_sys_window_actions
  345.  
  346.         ; if now we are resizing the window, dont change the cursor
  347.         mov     bl, [mouse.active_sys_window.action]
  348.         and     bl, mouse.WINDOW_RESIZE_S_FLAG or mouse.WINDOW_RESIZE_W_FLAG or mouse.WINDOW_RESIZE_E_FLAG
  349.         test    bl, bl
  350.         jnz     .end1
  351.  
  352.         cmp     al, mouse.WINDOW_RESIZE_SW_FLAG
  353.         jne     .not_sw
  354.         ; DEBUGF  1, "RESIZE SOUTH-WEST\n"
  355.  
  356.         mov     eax, [def_cursor_dresize2]
  357.  
  358.         jmp     .set_resizing_cursor
  359. .not_sw:
  360.         cmp     al, mouse.WINDOW_RESIZE_SE_FLAG
  361.         jne     .not_se
  362.         ; DEBUGF  1, "RESIZE SOUTH-EAST\n"
  363.  
  364.         mov     eax, [def_cursor_dresize1]
  365.  
  366.         jmp     .set_resizing_cursor
  367. .not_se:
  368.         cmp     al, mouse.WINDOW_RESIZE_W_FLAG
  369.         jne     .not_w
  370.         ; DEBUGF  1, "RESIZE WEST\n"
  371.  
  372.         mov     eax, [def_cursor_hresize]
  373.  
  374.         jmp     .set_resizing_cursor
  375. .not_w:
  376.         cmp     al, mouse.WINDOW_RESIZE_S_FLAG
  377.         jne     .not_s
  378.         ; DEBUGF  1, "RESIZE SOUTH\n"
  379.  
  380.         mov     eax, [def_cursor_vresize]
  381.  
  382.         jmp     .set_resizing_cursor
  383. .not_s:
  384.         cmp     al, mouse.WINDOW_RESIZE_E_FLAG
  385.         jne     .not_in_resize_area
  386.         ; DEBUGF  1, "RESIZE EAST\n"
  387.  
  388.         mov     eax, [def_cursor_hresize]
  389.  
  390. .set_resizing_cursor:
  391.         ; DEBUGF  1, ".set_resizing_cursor eax = %x\n", eax
  392.         ; change cursor to resizing cursor
  393.         shl     esi, BSF sizeof.APPDATA
  394.         add     esi, SLOT_BASE
  395.        
  396.         ; if resizing cursor we need (eax) isnt set already, set it
  397.         cmp     eax, [esi + APPDATA.cursor]
  398.         je      @f
  399.        
  400.         ; DEBUGF  1, "changing cursor to resizing\n"
  401.         xchg    eax, [esi + APPDATA.cursor] ; set resizing cursor, prev cursor goes to eax
  402.         ; save previous cursor (will be restored when we'll get out of the resizing area)
  403.         ; if we change resizing cursor to resizing cursor then dont update previous cursor
  404.         cmp     eax, [def_cursor_hresize]
  405.         je      @f
  406.         cmp     eax, [def_cursor_vresize]
  407.         je      @f
  408.         cmp     eax, [def_cursor_dresize1]
  409.         je      @f
  410.         cmp     eax, [def_cursor_dresize2]
  411.         je      @f
  412.  
  413.         mov     [esi + APPDATA.temp_cursor], eax ; save prev cursor
  414.  
  415. @@:
  416.         jmp     .end1
  417. .not_in_resize_area:
  418.         ; DEBUGF  1, ".not_in_resize_area\n"
  419.  
  420.         shl     esi, BSF sizeof.APPDATA
  421.         add     esi, SLOT_BASE
  422.         mov     eax, [esi + APPDATA.temp_cursor]
  423.  
  424.         test    eax, eax
  425.         jz      .end1
  426.        
  427.         ; restore prev cursor
  428.         mov     [esi + APPDATA.temp_cursor], 0
  429.         mov     [esi + APPDATA.cursor], eax
  430.  
  431. .end1:
  432.         pop     ebx eax
  433.  
  434.         cmp     [mouse.active_sys_button.pbid], 0
  435.         jnz     .exit
  436.  
  437.         mov     esi, [mouse.active_sys_window.pslot]
  438.         or      esi, esi
  439.         jz      .exit
  440.  
  441.         mov     eax, mouse.active_sys_window.new_box
  442.         mov     ebx, mouse.active_sys_window.old_box
  443.         mov     ecx, sizeof.BOX
  444.         call    memmove
  445.  
  446.         mov     dl, [mouse.active_sys_window.action]
  447.         test    dl, mouse.WINDOW_MOVE_FLAG
  448.         jz      .check_resize_w
  449.  
  450.         mov     eax, [mouse.state.pos.x]
  451.         sub     eax, [mouse.active_sys_window.delta.x]
  452.         mov     [mouse.active_sys_window.new_box.left], eax
  453.         mov     eax, [mouse.state.pos.y]
  454.         sub     eax, [mouse.active_sys_window.delta.y]
  455.         mov     [mouse.active_sys_window.new_box.top], eax
  456.  
  457.         mov     eax, [mouse.active_sys_window.new_box.left]
  458.         or      eax, eax
  459.         jge     @f
  460.         xor     eax, eax
  461.         mov     [mouse.active_sys_window.new_box.left], eax
  462.     @@:
  463.         add     eax, [mouse.active_sys_window.new_box.width]
  464.         cmp     eax, [_display.width]
  465.         jl      @f
  466.         sub     eax, [_display.width]
  467.         inc     eax
  468.         sub     [mouse.active_sys_window.new_box.left], eax
  469.     @@:
  470.         mov     eax, [mouse.active_sys_window.new_box.top]
  471.         or      eax, eax
  472.         jge     @f
  473.         xor     eax, eax
  474.         mov     [mouse.active_sys_window.new_box.top], eax
  475.     @@:
  476.         add     eax, [mouse.active_sys_window.new_box.height]
  477.         cmp     eax, [_display.height]
  478.         jl      .call_window_handler
  479.         sub     eax, [_display.height]
  480.         inc     eax
  481.         sub     [mouse.active_sys_window.new_box.top], eax
  482.         jmp     .call_window_handler
  483.  
  484.   .check_resize_w:
  485.         test    dl, mouse.WINDOW_RESIZE_W_FLAG
  486.         jz      .check_resize_s
  487.  
  488.         mov     eax, [mouse.state.pos.x]
  489.         sub     eax, [mouse.active_sys_window.delta.x]
  490.         mov     [mouse.active_sys_window.new_box.left], eax
  491.         sub     eax, [mouse.active_sys_window.old_box.left]
  492.         sub     [mouse.active_sys_window.new_box.width], eax
  493.  
  494.         mov     eax, [mouse.active_sys_window.new_box.width]
  495.         sub     eax, 127
  496.         jge     @f
  497.         add     [mouse.active_sys_window.new_box.left], eax
  498.         mov     [mouse.active_sys_window.new_box.width], 127
  499.     @@:
  500.         mov     eax, [mouse.active_sys_window.new_box.left]
  501.         or      eax, eax
  502.         jge     .check_resize_s
  503.         add     [mouse.active_sys_window.new_box.width], eax
  504.         xor     eax, eax
  505.         mov     [mouse.active_sys_window.new_box.left], eax
  506.  
  507.   .check_resize_s:
  508.         test    dl, mouse.WINDOW_RESIZE_S_FLAG
  509.         jz      .check_resize_e
  510.  
  511.         mov     eax, [mouse.state.pos.y]
  512.         add     eax, [mouse.active_sys_window.delta.y]
  513.         sub     eax, [mouse.active_sys_window.old_box.top]
  514.         mov     [mouse.active_sys_window.new_box.height], eax
  515.  
  516.         push    eax
  517.         mov     edi, esi
  518.         shl     edi, 5
  519.         add     edi, window_data
  520.         call    window._.get_rolledup_height
  521.         mov     ecx, eax
  522.         pop     eax
  523.         mov     eax, [mouse.active_sys_window.new_box.height]
  524.         cmp     eax, ecx
  525.         jge     @f
  526.         mov     eax, ecx
  527.         mov     [mouse.active_sys_window.new_box.height], eax
  528.     @@:
  529.         add     eax, [mouse.active_sys_window.new_box.top]
  530.         cmp     eax, [_display.height]
  531.         jl      .check_resize_e
  532.         sub     eax, [_display.height]
  533.         neg     eax
  534.         add     [mouse.active_sys_window.new_box.height], eax
  535.         mov     ecx, [_display.height]
  536.         cmp     ecx, eax
  537.         jg      .check_resize_e
  538.         mov     [mouse.active_sys_window.new_box.height], ecx
  539.  
  540.   .check_resize_e:
  541.         test    dl, mouse.WINDOW_RESIZE_E_FLAG
  542.         jz      .call_window_handler
  543.  
  544.         mov     eax, [mouse.state.pos.x]
  545.         add     eax, [mouse.active_sys_window.delta.x]
  546.         sub     eax, [mouse.active_sys_window.old_box.left]
  547.         mov     [mouse.active_sys_window.new_box.width], eax
  548.  
  549.         mov     eax, [mouse.active_sys_window.new_box.width]
  550.         cmp     eax, 127
  551.         jge     @f
  552.         mov     eax, 127
  553.         mov     [mouse.active_sys_window.new_box.width], eax
  554.     @@:
  555.         add     eax, [mouse.active_sys_window.new_box.left]
  556.         cmp     eax, [_display.width]
  557.         jl      .call_window_handler
  558.         sub     eax, [_display.width]
  559.         neg     eax
  560.         add     [mouse.active_sys_window.new_box.width], eax
  561.         mov     ecx, [_display.width]
  562.         cmp     ecx, eax
  563.         jg      .call_window_handler
  564.         mov     [mouse.active_sys_window.new_box.width], ecx
  565.  
  566.   .call_window_handler:
  567.         mov     eax, mouse.active_sys_window.old_box
  568.         mov     ebx, mouse.active_sys_window.new_box
  569.  
  570.         push    esi
  571.         mov     esi, mouse.active_sys_window.old_box
  572.         mov     edi, mouse.active_sys_window.new_box
  573.         mov     ecx, sizeof.BOX / 4
  574.         repe
  575.         cmpsd
  576.         pop     esi
  577.         je      .exit
  578.  
  579.         test    [fl_moving], 1
  580.         jnz     @f
  581.  
  582.         mov     [fl_moving], 1
  583.         push    edi
  584.         mov     edi, esi
  585.         shl     edi, 5
  586.         add     edi, WDATA.box + window_data
  587.         call    window._.draw_negative_box
  588.         pop     edi
  589.      @@:
  590.  
  591.  
  592.         mov     [mouse.active_sys_window.last_ticks], 0
  593.         call    sys_window_moving_handler
  594.  
  595.   .exit:
  596.         ret
  597.  
  598. align 4
  599. ;-----------------------------------------------------------------
  600. mouse._.find_sys_window_under_cursor:
  601. ; Find system window object which is currently visible on screen
  602. ; and has mouse cursor within its bounds
  603. ;< esi = process slot
  604. ;< edi = pointer to WDATA struct
  605.         mov     esi, [mouse.state.pos.y]
  606.         mov     esi, [d_width_calc_area + esi*4]
  607.  
  608.         add     esi, [_display.win_map]
  609.         add     esi, [mouse.state.pos.x]
  610.         movzx   esi, byte[esi]
  611.         mov     edi, esi
  612.         shl     edi, 5
  613.         add     edi, window_data
  614.         ret
  615.  
  616. align 4
  617. ;-----------------------------------------------------------------
  618. mouse._.activate_sys_window_under_cursor:
  619. ; activate and redraw window under cursor (if necessary)
  620.         call    mouse._.find_sys_window_under_cursor
  621.         movzx   esi, word[WIN_STACK + esi * 2]
  622.         lea     esi, [WIN_POS + esi * 2]
  623.         jmp     waredraw
  624.  
  625. align 4
  626. ;-----------------------------------------------------------------
  627. mouse._.find_sys_button_under_cursor:
  628. ; Find system button object which is currently visible on screen
  629. ; and has mouse cursor within its bounds
  630. ;< eax = pack[8(process slot), 24(button id)] or 0
  631. ;< ebx = pack[16(button x coord), 16(button y coord)]
  632.         push    ecx edx esi edi
  633.  
  634.         call    mouse._.find_sys_window_under_cursor
  635.         mov     edx, esi
  636.  
  637.         ; check if any process button contains cursor
  638.         mov     eax, [BTN_ADDR]
  639.         mov     ecx, [eax]
  640.         imul    esi, ecx, sizeof.SYS_BUTTON
  641.         add     esi, eax
  642.         inc     ecx
  643.         add     esi, sizeof.SYS_BUTTON
  644.  
  645.   .next_button:
  646.         dec     ecx
  647.         jz      .not_found
  648.  
  649.         add     esi, -sizeof.SYS_BUTTON
  650.  
  651.         ; does it belong to our process?
  652.         cmp     dx, [esi + SYS_BUTTON.pslot]
  653.         jne     .next_button
  654.  
  655.         ; does it contain cursor coordinates?
  656.         mov     eax, [mouse.state.pos.x]
  657.         sub     eax, [edi + WDATA.box.left]
  658.         sub     ax, [esi + SYS_BUTTON.left]
  659.         jl      .next_button
  660.         sub     ax, [esi + SYS_BUTTON.width]
  661.         jge     .next_button
  662.         mov     eax, [mouse.state.pos.y]
  663.         sub     eax, [edi + WDATA.box.top]
  664.         sub     ax, [esi + SYS_BUTTON.top]
  665.         jl      .next_button
  666.         sub     ax, [esi + SYS_BUTTON.height]
  667.         jge     .next_button
  668.  
  669.         ; okay, return it
  670.         shl     edx, 24
  671.         mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
  672.         mov     ax, [esi + SYS_BUTTON.id_lo]
  673.         and     eax, 0x0ffffff
  674.         or      eax, edx
  675.         mov     ebx, dword[esi + SYS_BUTTON.left - 2]
  676.         mov     bx, [esi + SYS_BUTTON.top]
  677.         jmp     .exit
  678.  
  679.   .not_found:
  680.         xor     eax, eax
  681.         xor     ebx, ebx
  682.  
  683.   .exit:
  684.         pop     edi esi edx ecx
  685.         ret
  686.  
  687. align 4
  688. ;-----------------------------------------------------------------
  689. mouse._.check_sys_window_actions:
  690. ;< eax = action flags or 0
  691.         ; is window movable?
  692.         test    byte[edi + WDATA.cl_titlebar + 3], 0x01
  693.         jnz     .no_action
  694.  
  695.         mov     eax, [mouse.state.pos.x]
  696.         mov     ebx, [mouse.state.pos.y]
  697.         sub     eax, [edi + WDATA.box.left]
  698.         sub     ebx, [edi + WDATA.box.top]
  699.  
  700.         ; is there a window titlebar under cursor?
  701.         push    eax
  702.         call    window._.get_titlebar_height
  703.         cmp     ebx, eax
  704.         pop     eax
  705.         jl      .move_action
  706.  
  707.         ; no there isn't, can it be resized then?
  708.         mov     dl, [edi + WDATA.fl_wstyle]
  709.         and     dl, 0x0f
  710. ; NOTE: dangerous optimization, revise if window types changed
  711. ; this currently implies only types 2 and 3 could be resized
  712.         test    dl, 2
  713.         jz      .no_action
  714.  
  715.         mov     ecx, [edi + WDATA.box.width]
  716.         add     ecx, -window.BORDER_SIZE
  717.         mov     edx, [edi + WDATA.box.height]
  718.         add     edx, -window.BORDER_SIZE
  719.  
  720.         ; is it rolled up?
  721.         test    [edi + WDATA.fl_wstate], WSTATE_ROLLEDUP
  722.         jnz     .resize_w_or_e_action
  723.  
  724.         cmp     eax, window.BORDER_SIZE
  725.         jl      .resize_w_action
  726.         cmp     eax, ecx
  727.         jg      .resize_e_action
  728.         cmp     ebx, edx
  729.         jle     .no_action
  730.  
  731.   .resize_s_action:
  732.         cmp     eax, window.BORDER_SIZE + 10
  733.         jl      .resize_sw_action
  734.         add     ecx, -10
  735.         cmp     eax, ecx
  736.         jge     .resize_se_action
  737.         mov     eax, mouse.WINDOW_RESIZE_S_FLAG
  738.         jmp     .exit
  739.  
  740.   .resize_w_or_e_action:
  741.         cmp     eax, window.BORDER_SIZE + 10
  742.         jl      .resize_w_action.direct
  743.         add     ecx, -10
  744.         cmp     eax, ecx
  745.         jg      .resize_e_action.direct
  746.         jmp     .no_action
  747.  
  748.   .resize_w_action:
  749.         add     edx, -10
  750.         cmp     ebx, edx
  751.         jge     .resize_sw_action
  752.   .resize_w_action.direct:
  753.         mov     eax, mouse.WINDOW_RESIZE_W_FLAG
  754.         jmp     .exit
  755.  
  756.   .resize_e_action:
  757.         add     edx, -10
  758.         cmp     ebx, edx
  759.         jge     .resize_se_action
  760.   .resize_e_action.direct:
  761.         mov     eax, mouse.WINDOW_RESIZE_E_FLAG
  762.         jmp     .exit
  763.  
  764.   .resize_sw_action:
  765.         mov     eax, mouse.WINDOW_RESIZE_SW_FLAG
  766.         jmp     .exit
  767.  
  768.   .resize_se_action:
  769.         mov     eax, mouse.WINDOW_RESIZE_SE_FLAG
  770.         jmp     .exit
  771.  
  772.   .move_action:
  773.         mov     eax, mouse.WINDOW_MOVE_FLAG
  774.         jmp     .exit
  775.  
  776.   .no_action:
  777.         xor     eax, eax
  778.  
  779.   .exit:
  780.         ret
  781. ;-----------------------------------------------------------------------------
  782.  
  783. align 4
  784. readmousepos:
  785. ; eax=0 screen relative
  786. ; eax=1 window relative
  787. ; eax=2 buttons pressed
  788. ; eax=3 buttons pressed ext
  789. ; eax=4 load cursor
  790. ; eax=5 set cursor
  791. ; eax=6 delete cursor
  792. ; eax=7 get mouse_z
  793. ; eax=8 load cursor unicode
  794.         cmp     ebx, 8
  795.         ja      @f
  796.         jmp     dword[.mousefn+ebx*4]
  797.  
  798. align 4
  799. .mousefn:
  800. dd  .msscreen
  801. dd  .mswin
  802. dd  .msbutton
  803. dd  .msbuttonExt
  804. dd  .app_load_cursor
  805. dd  .app_set_cursor
  806. dd  .app_delete_cursor
  807. dd  .msz
  808. dd  .loadCursorUni
  809.  
  810. .msscreen:
  811.         mov     eax, [MOUSE_X]
  812.         shl     eax, 16
  813.         mov     ax, [MOUSE_Y]
  814.         mov     [esp + SYSCALL_STACK.eax], eax
  815. @@:
  816.         ret
  817.  
  818. .mswin:
  819.         mov     eax, [MOUSE_X]
  820.         shl     eax, 16
  821.         mov     ax, [MOUSE_Y]
  822.         mov     esi, [current_slot_idx]
  823.         shl     esi, BSF sizeof.WDATA
  824.         mov     bx, word [esi + window_data + WDATA.box.left]
  825.         shl     ebx, 16
  826.         mov     bx, word [esi + window_data + WDATA.box.top]
  827.         sub     eax, ebx
  828.         mov     edi, [current_slot]
  829.         sub     ax, word[edi + APPDATA.wnd_clientbox.top]
  830.         rol     eax, 16
  831.         sub     ax, word[edi + APPDATA.wnd_clientbox.left]
  832.         rol     eax, 16
  833.         mov     [esp + SYSCALL_STACK.eax], eax
  834.         ret
  835.  
  836. .msbutton:
  837.         movzx   eax, byte [BTN_DOWN]
  838.         mov     [esp + SYSCALL_STACK.eax], eax
  839.         ret
  840.  
  841. .msbuttonExt:
  842.         mov     eax, [BTN_DOWN]
  843.         mov     [esp + SYSCALL_STACK.eax], eax
  844.         ret
  845.  
  846. .app_load_cursor:
  847.         cmp     ecx, OS_BASE
  848.         jae     @f
  849.         stdcall load_cursor, ecx, edx
  850.         mov     [esp + SYSCALL_STACK.eax], eax
  851. @@:
  852.         ret
  853.  
  854. .loadCursorUni:
  855.         cmp     ecx, OS_BASE
  856.         jae     @b
  857.         push    ecx edx
  858.         stdcall kernel_alloc, maxPathLength
  859.         mov     edi, eax
  860.         pop     eax esi
  861.         push    edi
  862.         call    getFullPath
  863.         pop     ebp
  864.         test    eax, eax
  865.         jz      @f
  866.         stdcall load_cursor, ebp, LOAD_FROM_FILE
  867.         mov     [esp + SYSCALL_STACK.eax], eax
  868. @@:
  869.         stdcall kernel_free, ebp
  870.         ret
  871.  
  872. .app_set_cursor:
  873.         stdcall set_cursor, ecx
  874.         mov     [esp + SYSCALL_STACK.eax], eax
  875.         ret
  876.  
  877. .app_delete_cursor:
  878.         stdcall delete_cursor, ecx
  879.         mov     [esp + SYSCALL_STACK.eax], eax
  880.         ret
  881.  
  882. .msz:
  883.         mov     edi, [thread_count]
  884.         movzx   edi, word [WIN_POS + edi*2]
  885.         cmp     edi, [current_slot_idx]
  886.         jne     @f
  887.         mov     ax, [MOUSE_SCROLL_H]
  888.         shl     eax, 16
  889.         mov     ax, [MOUSE_SCROLL_V]
  890.         mov     [esp + SYSCALL_STACK.eax], eax
  891.         and     [MOUSE_SCROLL_H], word 0
  892.         and     [MOUSE_SCROLL_V], word 0
  893.         ret
  894. @@:
  895.         and     [esp + SYSCALL_STACK.eax], dword 0
  896.         ret
  897.