Subversion Repositories Kolibri OS

Rev

Rev 9930 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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