Subversion Repositories Kolibri OS

Rev

Rev 1362 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
  4. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. $Revision: 1376 $
  10.  
  11.  
  12. button._.MAX_BUTTONS = 4095
  13.  
  14.  
  15. ;==============================================================================
  16. ;///// public functions ///////////////////////////////////////////////////////
  17. ;==============================================================================
  18.  
  19. struc SYS_BUTTON
  20. {
  21.   .pslot  dw ?
  22.   .id_lo  dw ?
  23.   .left   dw ?
  24.   .width  dw ?
  25.   .top    dw ?
  26.   .height dw ?
  27.   .id_hi  dw ?
  28.   .sizeof:
  29. }
  30. virtual at 0
  31.   SYS_BUTTON SYS_BUTTON
  32. end virtual
  33.  
  34. iglobal
  35.   mx                dw 0x0 ; keeps the x mouse's position when it was clicked
  36.   my                dw 0x0 ; keeps the y mouse's position when it was clicked
  37.   bPressedMouseXY_B db 0x0
  38.   btn_down_determ   db 0x0
  39. endg
  40.  
  41. align 4
  42. ;------------------------------------------------------------------------------
  43. syscall_button: ;///// system function 8 //////////////////////////////////////
  44. ;------------------------------------------------------------------------------
  45. ;? Define/undefine GUI button object
  46. ;------------------------------------------------------------------------------
  47. ;; Define button:
  48. ;> ebx = pack[16(x), 16(width)]
  49. ;> ecx = pack[16(y), 16(height)]
  50. ;> edx = pack[8(flags), 24(button identifier)]
  51. ;>       flags bits:
  52. ;>          7 (31) = 0
  53. ;>          6 (30) = don't draw button
  54. ;>          5 (29) = don't draw button frame when pressed
  55. ;> esi = button color
  56. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  57. ;; Undefine button:
  58. ;> edx = pack[8(flags), 24(button identifier)]
  59. ;>       flags bits:
  60. ;>          7 (31) = 1
  61. ;------------------------------------------------------------------------------
  62.         ; do we actually need to undefine the button?
  63.         test    edx, 0x80000000
  64.         jnz     .remove_button
  65.  
  66.         ; do we have free button slots available?
  67.         mov     edi, [BTN_ADDR]
  68.         mov     eax, [edi]
  69.         cmp     eax, button._.MAX_BUTTONS
  70.         jge     .exit
  71.  
  72.         ; does it have positive size? (otherwise it doesn't have sense)
  73.         or      bx, bx
  74.         jle     .exit
  75.         or      cx, cx
  76.         jle     .exit
  77.  
  78.         ; make coordinates clientbox-relative
  79.         push    eax
  80.         mov     eax, [current_slot]
  81.         rol     ebx, 16
  82.         add     bx, word[eax + APPDATA.wnd_clientbox.left]
  83.         rol     ebx, 16
  84.         rol     ecx, 16
  85.         add     cx, word[eax + APPDATA.wnd_clientbox.top]
  86.         rol     ecx, 16
  87.         pop     eax
  88.  
  89.         ; basic checks passed, define the button
  90.         push    ebx ecx edx
  91.         inc     eax
  92.         mov     [edi], ax
  93.         shl     eax, 4
  94.         add     edi, eax
  95.         ; NOTE: this code doesn't rely on SYS_BUTTON struct, please revise it
  96.         ;       if you change something
  97.         mov     ax, [CURRENT_TASK]
  98.         stosw
  99.         mov     ax, dx
  100.         stosw               ; button id number: bits 0-15
  101.         mov     eax, ebx
  102.         rol     eax, 16
  103.         stosd               ; x start | x size
  104.         mov     eax, ecx
  105.         rol     eax, 16
  106.         stosd               ; y start | y size
  107.         mov     eax, edx
  108.         shr     eax, 16
  109.         stosw               ; button id number: bits 16-31
  110.         pop     edx ecx ebx
  111.  
  112.         ; do we also need to draw the button?
  113.         test    edx, 0x40000000
  114.         jnz     .exit
  115.  
  116.         ; draw button body
  117.  
  118.         pushad
  119.  
  120.         ; calculate window-relative coordinates
  121.         movzx   edi, cx
  122.         shr     ebx, 16
  123.         shr     ecx, 16
  124.         mov     eax, [TASK_BASE]
  125.         add     ebx, [eax - twdw + WDATA.box.left]
  126.         add     ecx, [eax - twdw + WDATA.box.top]
  127.         mov     eax, ebx
  128.         shl     eax, 16
  129.         mov     ax, bx
  130.         add     ax, word[esp + 16]
  131.         mov     ebx, ecx
  132.         shl     ebx, 16
  133.         mov     bx, cx
  134.  
  135.         ; calculate initial color
  136.         mov     ecx, esi
  137.         cmp     [buttontype], 0
  138.         je      @f
  139.         call    button._.incecx2
  140.  
  141.         ; set button height counter
  142.     @@: mov     edx, edi
  143.  
  144.   .next_line:
  145.         call    button._.button_dececx
  146.         push    edi
  147.         xor     edi, edi
  148.         call    [draw_line]
  149.         pop     edi
  150.         add     ebx, 0x00010001
  151.         dec     edx
  152.         jnz     .next_line
  153.  
  154.         popad
  155.  
  156.         ; draw button frame
  157.  
  158.         push    ebx ecx
  159.  
  160.         ; calculate window-relative coordinates
  161.         shr     ebx, 16
  162.         shr     ecx, 16
  163.         mov     eax, [TASK_BASE]
  164.         add     ebx, [eax - twdw + WDATA.box.left]
  165.         add     ecx, [eax - twdw + WDATA.box.top]
  166.  
  167.         ; top border
  168.         mov     eax, ebx
  169.         shl     eax, 16
  170.         mov     ax, bx
  171.         add     ax, [esp + 4]
  172.         mov     ebx, ecx
  173.         shl     ebx, 16
  174.         mov     bx, cx
  175.         push    ebx
  176.         xor     edi, edi
  177.         mov     ecx, esi
  178.         call    button._.incecx
  179.         call    [draw_line]
  180.  
  181.         ; bottom border
  182.         movzx   edx, word[esp + 4 + 0]
  183.         add     ebx, edx
  184.         shl     edx, 16
  185.         add     ebx, edx
  186.         mov     ecx, esi
  187.         call    button._.dececx
  188.         call    [draw_line]
  189.  
  190.         ; left border
  191.         pop     ebx
  192.         push    edx
  193.         mov     edx, eax
  194.         shr     edx, 16
  195.         mov     ax, dx
  196.         mov     edx, ebx
  197.         shr     edx, 16
  198.         mov     bx, dx
  199.         add     bx, [esp + 4 + 0]
  200.         pop     edx
  201.         mov     ecx, esi
  202.         call    button._.incecx
  203.         call    [draw_line]
  204.  
  205.         ; right border
  206.         mov     dx, [esp + 4]
  207.         add     ax, dx
  208.         shl     edx, 16
  209.         add     eax, edx
  210.         add     ebx, 0x00010000
  211.         mov     ecx, esi
  212.         call    button._.dececx
  213.         call    [draw_line]
  214.  
  215.         pop     ecx ebx
  216.  
  217.   .exit:
  218.         ret
  219.  
  220. ; FIXME: mutex needed
  221. syscall_button.remove_button:
  222.         and     edx, 0x00ffffff
  223.         mov     edi, [BTN_ADDR]
  224.         mov     ebx, [edi]
  225.         inc     ebx
  226.         imul    esi, ebx, SYS_BUTTON.sizeof
  227.         add     esi, edi
  228.         xor     ecx, ecx
  229.         add     ecx, -SYS_BUTTON.sizeof
  230.  
  231.   .next_button:
  232.         dec     ebx
  233.         jz      .exit
  234.  
  235.         add     ecx, SYS_BUTTON.sizeof
  236.         add     esi, -SYS_BUTTON.sizeof
  237.  
  238.         ; does it belong to our process?
  239.         mov     ax, [CURRENT_TASK]
  240.         cmp     ax, [esi + SYS_BUTTON.pslot]
  241.         jne     .next_button
  242.  
  243.         ; does the identifier match?
  244.         mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
  245.         mov     ax, [esi + SYS_BUTTON.id_lo]
  246.         and     eax, 0x00ffffff
  247.         cmp     edx, eax
  248.         jne     .next_button
  249.  
  250.         ; okay, undefine it
  251.         push    ebx
  252.         mov     ebx, esi
  253.         lea     eax, [esi + SYS_BUTTON.sizeof]
  254.         call    memmove
  255.         dec     dword[edi]
  256.         add     ecx, -SYS_BUTTON.sizeof
  257.         pop     ebx
  258.         jmp     .next_button
  259.  
  260.   .exit:
  261.         ret
  262.  
  263. align 4
  264. ;------------------------------------------------------------------------------
  265. check_buttons: ;///////////////////////////////////////////////////////////////
  266. ;------------------------------------------------------------------------------
  267. ;? <description>
  268. ;------------------------------------------------------------------------------
  269.         cmp     byte[BTN_DOWN], 0    ; mouse buttons pressed
  270.         jnz     @f
  271.         mov     [bPressedMouseXY_B], 0
  272.         ret
  273.  
  274.     @@: pushad
  275.         xor     esi, esi
  276.         mov     edi, [BTN_ADDR]
  277.         mov     edx, [edi]
  278.         test    edx, edx
  279.         jne     @f
  280.         popad
  281.         ret
  282.  
  283.         ;here i catch the coordinates when the mouse's button is clicked
  284.     @@: push    ax
  285.         cmp     [bPressedMouseXY_B], 0 ; FALSE
  286.         jnz     @f
  287.         mov     [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
  288.         mov     ax, [MOUSE_X]
  289.         mov     [mx], ax
  290.         mov     ax, [MOUSE_Y]
  291.         mov     [my], ax
  292.     @@: pop     ax
  293.         ;and it is only refreshed after the mouse's button release
  294.  
  295.         push    esi
  296.         inc     edx
  297.         push    edx
  298.  
  299.   .buttonnewcheck:
  300.         pop     edx
  301.         pop     esi
  302.         inc     esi
  303.         cmp     edx, esi
  304.         jge     .bch
  305.  
  306.         popad
  307.         ret
  308.  
  309.   .bch:
  310.         push    esi
  311.         push    edx
  312.         mov     eax, esi
  313.         shl     eax, 4
  314.         add     eax, edi
  315.  
  316.         ; check that button is at top of windowing stack
  317.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  318.         movzx   ecx, word[WIN_STACK + ebx * 2]
  319.         cmp     ecx, [TASK_COUNT]
  320.         jne     .buttonnewcheck
  321.  
  322.         ; check that button start is inside window x/y end
  323.         shl     ebx, 5
  324.  
  325.         test    [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
  326.         jnz     .buttonnewcheck
  327.  
  328.         movzx   edx, [eax + SYS_BUTTON.left]
  329.         cmp     edx, [window_data + ebx + WDATA.box.width] ;ecx
  330.         jge     .buttonnewcheck
  331.  
  332.         movzx   edx, [eax + SYS_BUTTON.top]
  333.         cmp     edx, [window_data + ebx + WDATA.box.height] ;ecx
  334.         jge     .buttonnewcheck
  335.  
  336.         ; check coordinates
  337.  
  338.         ; mouse x >= button x ?
  339.         add     ebx, window_data
  340.         mov     ecx, [ebx + WDATA.box.left]
  341.         movzx   edx, [eax + SYS_BUTTON.left]
  342.         add     edx, ecx
  343.         mov     cx, [mx]   ;mov cx,[MOUSE_X]
  344.         cmp     edx, ecx
  345.         jg      .buttonnewcheck
  346.  
  347.         movzx   ebx, [eax + SYS_BUTTON.width]
  348.         add     edx, ebx
  349.         cmp     ecx, edx
  350.         jg      .buttonnewcheck
  351.  
  352.         ; mouse y >= button y ?
  353.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  354.         shl     ebx, 5
  355.         add     ebx, window_data
  356.         mov     ecx, [ebx + WDATA.box.top]
  357.         movzx   edx, [eax + SYS_BUTTON.top]
  358.         add     edx, ecx
  359.         mov     cx, [my]  ;mov cx,[MOUSE_Y]
  360.         cmp     edx, ecx
  361.         jg      .buttonnewcheck
  362.  
  363.         movzx   ebx, [eax + SYS_BUTTON.height]
  364.         add     edx, ebx
  365.         cmp     ecx, edx
  366.         jg      .buttonnewcheck
  367.  
  368.         ; mouse on button
  369.  
  370.         pop     edx
  371.         pop     esi
  372.  
  373.         mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]     ; button id : bits 16-31
  374.         mov     bx, [eax + SYS_BUTTON.id_lo]       ; button id : bits 00-16
  375.         push    ebx
  376.  
  377.         mov     byte[MOUSE_DOWN], 1  ; no mouse down checks
  378.         call    button._.negative_button
  379.  
  380.         pushad
  381.         push    eax
  382.         mov     al, [BTN_DOWN]
  383.         mov     byte[btn_down_determ], al
  384.         pop     eax
  385.  
  386.   .cbwaitmouseup:
  387.         call    checkidle
  388.         call    [draw_pointer]
  389.  
  390.         pushad
  391.         call    stack_handler
  392.         popad
  393.  
  394.         cmp     byte[BTN_DOWN], 0  ; mouse buttons pressed ?
  395.         jnz     .cbwaitmouseup
  396.         popad
  397.  
  398.         call    button._.negative_button
  399.         mov     byte[MOUSE_BACKGROUND], 0  ; no mouse background
  400.         mov     byte[DONT_DRAW_MOUSE], 0  ; draw mouse
  401.  
  402.         ; check coordinates
  403.         pusha
  404.  
  405.         ; mouse x >= button x ?
  406.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  407.         shl     ebx, 5
  408.         add     ebx, window_data
  409.         mov     ecx, [ebx + WDATA.box.left]
  410.         movzx   edx, [eax + SYS_BUTTON.left]
  411.         add     edx, ecx
  412.         mov     cx, [MOUSE_X]
  413.         cmp     edx, ecx
  414.         jg      .no_on_button ;if we release the pointer out of the button area
  415.  
  416.         movzx   ebx, [eax + SYS_BUTTON.width]
  417.         add     edx, ebx
  418.         cmp     ecx, edx
  419.         jg      .no_on_button
  420.  
  421.         ; mouse y >= button y ?
  422.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  423.         shl     ebx, 5
  424.         add     ebx, window_data
  425.         mov     ecx, [ebx + WDATA.box.top]
  426.         movzx   edx, [eax + SYS_BUTTON.top]
  427.         add     edx, ecx
  428.         mov     cx, [MOUSE_Y]
  429.         cmp     edx, ecx
  430.         jg      .no_on_button
  431.  
  432.         movzx   ebx, [eax + SYS_BUTTON.height]
  433.         add     edx, ebx
  434.         cmp     ecx, edx
  435.         jg      .no_on_button
  436.  
  437.         popa
  438.  
  439.         mov     byte[BTN_COUNT], 1 ; no of buttons in buffer
  440.         pop     ebx
  441.         mov     [BTN_BUFF], ebx   ; lets put the button id in buffer
  442.         push    ebx
  443.         pusha
  444.         jmp     .yes_on_button
  445.  
  446.   .no_on_button:
  447.         mov     byte[BTN_COUNT], 0 ; no of buttons in buffer
  448.  
  449.   .yes_on_button:
  450.         mov     byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
  451.         popa
  452.         pop     ebx
  453.         popa
  454.         ret
  455.  
  456. ;==============================================================================
  457. ;///// private functions //////////////////////////////////////////////////////
  458. ;==============================================================================
  459.  
  460. ;------------------------------------------------------------------------------
  461. button._.dececx: ;/////////////////////////////////////////////////////////////
  462. ;------------------------------------------------------------------------------
  463. ;? <description>
  464. ;------------------------------------------------------------------------------
  465.         sub     cl, 0x20
  466.         jnc     @f
  467.         xor     cl, cl
  468.     @@: sub     ch, 0x20
  469.         jnc     @f
  470.         xor     ch, ch
  471.     @@: rol     ecx, 16
  472.         sub     cl, 0x20
  473.         jnc     @f
  474.         xor     cl, cl
  475.     @@: rol     ecx, 16
  476.         ret
  477.  
  478. ;------------------------------------------------------------------------------
  479. button._.incecx: ;/////////////////////////////////////////////////////////////
  480. ;------------------------------------------------------------------------------
  481. ;? <description>
  482. ;------------------------------------------------------------------------------
  483.         add     cl, 0x20
  484.         jnc     @f
  485.         or      cl, -1
  486.     @@: add     ch, 0x20
  487.         jnc     @f
  488.         or      ch, -1
  489.     @@: rol     ecx, 16
  490.         add     cl, 0x20
  491.         jnc     @f
  492.         or      cl, -1
  493.     @@: rol     ecx, 16
  494.         ret
  495.  
  496. ;------------------------------------------------------------------------------
  497. button._.incecx2: ;////////////////////////////////////////////////////////////
  498. ;------------------------------------------------------------------------------
  499. ;? <description>
  500. ;------------------------------------------------------------------------------
  501.         add     cl, 0x14
  502.         jnc     @f
  503.         or      cl, -1
  504.     @@: add     ch, 0x14
  505.         jnc     @f
  506.         or      ch, -1
  507.     @@: rol     ecx, 16
  508.         add     cl, 0x14
  509.         jnc     @f
  510.         or      cl, -1
  511.     @@: rol     ecx, 16
  512.         ret
  513.  
  514. ;------------------------------------------------------------------------------
  515. button._.button_dececx: ;//////////////////////////////////////////////////////
  516. ;------------------------------------------------------------------------------
  517. ;? <description>
  518. ;------------------------------------------------------------------------------
  519.         cmp     [buttontype], 1
  520.         jne     .finish
  521.  
  522.         push    eax
  523.         mov     al, 1
  524.         cmp     edi, 20
  525.         jg      @f
  526.         mov     al, 2
  527.  
  528.     @@: sub     cl, al
  529.         jnc     @f
  530.         xor     cl, cl
  531.     @@: sub     ch, al
  532.         jnc     @f
  533.         xor     ch, ch
  534.     @@: rol     ecx, 16
  535.         sub     cl, al
  536.         jnc     @f
  537.         xor     cl, cl
  538.     @@: rol     ecx, 16
  539.  
  540.         pop     eax
  541.  
  542.   .finish:
  543.         ret
  544.  
  545. ;------------------------------------------------------------------------------
  546. button._.negative_button: ;////////////////////////////////////////////////////
  547. ;------------------------------------------------------------------------------
  548. ;? <description>
  549. ;------------------------------------------------------------------------------
  550.         ; if requested, do not display button border on press.
  551.         test    ebx, 0x20000000
  552.         jnz     .exit
  553.  
  554.         pushad
  555.  
  556.         xchg    esi, eax
  557.  
  558.         movzx   ecx, [esi + SYS_BUTTON.pslot]
  559.         shl     ecx, 5
  560.         add     ecx, window_data
  561.  
  562.         mov     eax, dword[esi + SYS_BUTTON.left]
  563.         mov     ebx, dword[esi + SYS_BUTTON.top]
  564.         add     eax, [ecx + WDATA.box.left]
  565.         add     ebx, [ecx + WDATA.box.top]
  566.         push    eax ebx
  567.         pop     edx ecx
  568.         rol     eax, 16
  569.         rol     ebx, 16
  570.         add     ax, cx
  571.         add     bx, dx
  572.  
  573.         mov     esi, 0x01000000
  574.         call    draw_rectangle.forced
  575.  
  576.         popad
  577.  
  578.   .exit:
  579.         ret
  580.