Subversion Repositories Kolibri OS

Rev

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