Subversion Repositories Kolibri OS

Rev

Rev 1300 | Rev 1341 | 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: 1334 $
  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 arguments:
  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 arguments:
  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.         mov     ebx, esi
  252.         lea     eax, [esi + SYS_BUTTON.sizeof]
  253.         call    memmove
  254.         dec     dword[edi]
  255.         add     ecx, -SYS_BUTTON.sizeof
  256.         jmp     .next_button
  257.  
  258.   .exit:
  259.         ret
  260.  
  261. align 4
  262. ;------------------------------------------------------------------------------
  263. check_buttons: ;///////////////////////////////////////////////////////////////
  264. ;------------------------------------------------------------------------------
  265. ; <description>
  266. ;------------------------------------------------------------------------------
  267.         cmp     byte[BTN_DOWN], 0    ; mouse buttons pressed
  268.         jnz     @f
  269.         mov     [bPressedMouseXY_B], 0
  270.         ret
  271.  
  272.     @@: pushad
  273.         xor     esi, esi
  274.         mov     edi, [BTN_ADDR]
  275.         mov     edx, [edi]
  276.         test    edx, edx
  277.         jne     @f
  278.         popad
  279.         ret
  280.  
  281.         ;here i catch the coordinates when the mouse's button is clicked
  282.     @@: push    ax
  283.         cmp     [bPressedMouseXY_B], 0 ; FALSE
  284.         jnz     @f
  285.         mov     [bPressedMouseXY_B], 1 ; TRUE - it was already clicked
  286.         mov     ax, [MOUSE_X]
  287.         mov     [mx], ax
  288.         mov     ax, [MOUSE_Y]
  289.         mov     [my], ax
  290.     @@: pop     ax
  291.         ;and it is only refreshed after the mouse's button release
  292.  
  293.         push    esi
  294.         inc     edx
  295.         push    edx
  296.  
  297.   .buttonnewcheck:
  298.         pop     edx
  299.         pop     esi
  300.         inc     esi
  301.         cmp     edx, esi
  302.         jge     .bch
  303.  
  304.         popad
  305.         ret
  306.  
  307.   .bch:
  308.         push    esi
  309.         push    edx
  310.         mov     eax, esi
  311.         shl     eax, 4
  312.         add     eax, edi
  313.  
  314.         ; check that button is at top of windowing stack
  315.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  316.         movzx   ecx, word[WIN_STACK + ebx * 2]
  317.         cmp     ecx, [TASK_COUNT]
  318.         jne     .buttonnewcheck
  319.  
  320.         ; check that button start is inside window x/y end
  321.         shl     ebx, 5
  322.  
  323.         test    [ebx + window_data + WDATA.fl_wstate], WSTATE_MINIMIZED
  324.         jnz     .buttonnewcheck
  325.  
  326.         movzx   edx, [eax + SYS_BUTTON.left]
  327.         cmp     edx, [window_data + ebx + WDATA.box.width] ;ecx
  328.         jge     .buttonnewcheck
  329.  
  330.         movzx   edx, [eax + SYS_BUTTON.top]
  331.         cmp     edx, [window_data + ebx + WDATA.box.height] ;ecx
  332.         jge     .buttonnewcheck
  333.  
  334.         ; check coordinates
  335.  
  336.         ; mouse x >= button x ?
  337.         add     ebx, window_data
  338.         mov     ecx, [ebx + WDATA.box.left]
  339.         movzx   edx, [eax + SYS_BUTTON.left]
  340.         add     edx, ecx
  341.         mov     cx, [mx]   ;mov cx,[MOUSE_X]
  342.         cmp     edx, ecx
  343.         jg      .buttonnewcheck
  344.  
  345.         movzx   ebx, [eax + SYS_BUTTON.width]
  346.         add     edx, ebx
  347.         cmp     ecx, edx
  348.         jg      .buttonnewcheck
  349.  
  350.         ; mouse y >= button y ?
  351.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  352.         shl     ebx, 5
  353.         add     ebx, window_data
  354.         mov     ecx, [ebx + WDATA.box.top]
  355.         movzx   edx, [eax + SYS_BUTTON.top]
  356.         add     edx, ecx
  357.         mov     cx, [my]  ;mov cx,[MOUSE_Y]
  358.         cmp     edx, ecx
  359.         jg      .buttonnewcheck
  360.  
  361.         movzx   ebx, [eax + SYS_BUTTON.height]
  362.         add     edx, ebx
  363.         cmp     ecx, edx
  364.         jg      .buttonnewcheck
  365.  
  366.         ; mouse on button
  367.  
  368.         pop     edx
  369.         pop     esi
  370.  
  371.         mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]     ; button id : bits 16-31
  372.         mov     bx, [eax + SYS_BUTTON.id_lo]       ; button id : bits 00-16
  373.         push    ebx
  374.  
  375.         mov     byte[MOUSE_DOWN], 1  ; no mouse down checks
  376.         call    button._.negative_button
  377.  
  378.         pushad
  379.         push    eax
  380.         mov     al, [BTN_DOWN]
  381.         mov     byte[btn_down_determ], al
  382.         pop     eax
  383.  
  384.   .cbwaitmouseup:
  385.         call    checkidle
  386.         call    [draw_pointer]
  387.  
  388.         pushad
  389.         call    stack_handler
  390.         popad
  391.  
  392.         cmp     byte[BTN_DOWN], 0  ; mouse buttons pressed ?
  393.         jnz     .cbwaitmouseup
  394.         popad
  395.  
  396.         call    button._.negative_button
  397.         mov     byte[MOUSE_BACKGROUND], 0  ; no mouse background
  398.         mov     byte[DONT_DRAW_MOUSE], 0  ; draw mouse
  399.  
  400.         ; check coordinates
  401.         pusha
  402.  
  403.         ; mouse x >= button x ?
  404.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  405.         shl     ebx, 5
  406.         add     ebx, window_data
  407.         mov     ecx, [ebx + WDATA.box.left]
  408.         movzx   edx, [eax + SYS_BUTTON.left]
  409.         add     edx, ecx
  410.         mov     cx, [MOUSE_X]
  411.         cmp     edx, ecx
  412.         jg      .no_on_button ;if we release the pointer out of the button area
  413.  
  414.         movzx   ebx, [eax + SYS_BUTTON.width]
  415.         add     edx, ebx
  416.         cmp     ecx, edx
  417.         jg      .no_on_button
  418.  
  419.         ; mouse y >= button y ?
  420.         movzx   ebx, [eax + SYS_BUTTON.pslot]
  421.         shl     ebx, 5
  422.         add     ebx, window_data
  423.         mov     ecx, [ebx + WDATA.box.top]
  424.         movzx   edx, [eax + SYS_BUTTON.top]
  425.         add     edx, ecx
  426.         mov     cx, [MOUSE_Y]
  427.         cmp     edx, ecx
  428.         jg      .no_on_button
  429.  
  430.         movzx   ebx, [eax + SYS_BUTTON.height]
  431.         add     edx, ebx
  432.         cmp     ecx, edx
  433.         jg      .no_on_button
  434.  
  435.         popa
  436.  
  437.         mov     byte[BTN_COUNT], 1 ; no of buttons in buffer
  438.         pop     ebx
  439.         mov     [BTN_BUFF], ebx   ; lets put the button id in buffer
  440.         push    ebx
  441.         pusha
  442.         jmp     .yes_on_button
  443.  
  444.   .no_on_button:
  445.         mov     byte[BTN_COUNT], 0 ; no of buttons in buffer
  446.  
  447.   .yes_on_button:
  448.         mov     byte[MOUSE_DOWN], 0 ; mouse down -> do not draw
  449.         popa
  450.         pop     ebx
  451.         popa
  452.         ret
  453.  
  454. ;==============================================================================
  455. ;///// private functions //////////////////////////////////////////////////////
  456. ;==============================================================================
  457.  
  458. ;------------------------------------------------------------------------------
  459. button._.dececx: ;/////////////////////////////////////////////////////////////
  460. ;------------------------------------------------------------------------------
  461. ; <description>
  462. ;------------------------------------------------------------------------------
  463.         sub     cl, 0x20
  464.         jnc     @f
  465.         xor     cl, cl
  466.     @@: sub     ch, 0x20
  467.         jnc     @f
  468.         xor     ch, ch
  469.     @@: rol     ecx, 16
  470.         sub     cl, 0x20
  471.         jnc     @f
  472.         xor     cl, cl
  473.     @@: rol     ecx, 16
  474.         ret
  475.  
  476. ;------------------------------------------------------------------------------
  477. button._.incecx: ;/////////////////////////////////////////////////////////////
  478. ;------------------------------------------------------------------------------
  479. ; <description>
  480. ;------------------------------------------------------------------------------
  481.         add     cl, 0x20
  482.         jnc     @f
  483.         or      cl, -1
  484.     @@: add     ch, 0x20
  485.         jnc     @f
  486.         or      ch, -1
  487.     @@: rol     ecx, 16
  488.         add     cl, 0x20
  489.         jnc     @f
  490.         or      cl, -1
  491.     @@: rol     ecx, 16
  492.         ret
  493.  
  494. ;------------------------------------------------------------------------------
  495. button._.incecx2: ;////////////////////////////////////////////////////////////
  496. ;------------------------------------------------------------------------------
  497. ; <description>
  498. ;------------------------------------------------------------------------------
  499.         add     cl, 0x14
  500.         jnc     @f
  501.         or      cl, -1
  502.     @@: add     ch, 0x14
  503.         jnc     @f
  504.         or      ch, -1
  505.     @@: rol     ecx, 16
  506.         add     cl, 0x14
  507.         jnc     @f
  508.         or      cl, -1
  509.     @@: rol     ecx, 16
  510.         ret
  511.  
  512. ;------------------------------------------------------------------------------
  513. button._.button_dececx: ;//////////////////////////////////////////////////////
  514. ;------------------------------------------------------------------------------
  515. ; <description>
  516. ;------------------------------------------------------------------------------
  517.         cmp     [buttontype], 1
  518.         jne     .finish
  519.  
  520.         push    eax
  521.         mov     al, 1
  522.         cmp     edi, 20
  523.         jg      @f
  524.         mov     al, 2
  525.  
  526.     @@: sub     cl, al
  527.         jnc     @f
  528.         xor     cl, cl
  529.     @@: sub     ch, al
  530.         jnc     @f
  531.         xor     ch, ch
  532.     @@: rol     ecx, 16
  533.         sub     cl, al
  534.         jnc     @f
  535.         xor     cl, cl
  536.     @@: rol     ecx, 16
  537.  
  538.         pop     eax
  539.  
  540.   .finish:
  541.         ret
  542.  
  543. ;------------------------------------------------------------------------------
  544. button._.negative_button: ;////////////////////////////////////////////////////
  545. ;------------------------------------------------------------------------------
  546. ; <description>
  547. ;------------------------------------------------------------------------------
  548.         ; If requested, do not display button border on press.
  549.         test    ebx, 0x20000000
  550.         jz      .draw_negative_button
  551.         ret
  552.  
  553.   .draw_negative_button:
  554.         pushad
  555.  
  556.         mov     ebx, dword[eax + SYS_BUTTON.left]
  557.         mov     ecx, dword[eax + SYS_BUTTON.top]
  558.         rol     ebx, 16
  559.         rol     ecx, 16
  560.         push    ebx ecx
  561.  
  562.         ; calculate window-relative coordinates
  563.         shr     ebx, 16
  564.         shr     ecx, 16
  565.         movzx   eax, word[eax + SYS_BUTTON.pslot]
  566.         shl     eax, 5
  567.         add     eax, window_data
  568.         add     ebx, [eax + WDATA.box.left]
  569.         add     ecx, [eax + WDATA.box.top]
  570.  
  571.         xor     edi, edi
  572.         inc     edi
  573.  
  574.         ; top border
  575.         mov     eax, ebx
  576.         shl     eax, 16
  577.         mov     ax, bx
  578.         add     ax, [esp + 4]
  579.         mov     ebx, ecx
  580.         shl     ebx, 16
  581.         mov     bx, cx
  582.         push    ebx
  583.         mov     ecx, 0x01000000
  584.         call    [draw_line]
  585.  
  586.         ; bottom border
  587.         movzx   edx, word[esp + 4 + 0]
  588.         add     ebx, edx
  589.         shl     edx, 16
  590.         add     ebx, edx
  591.         call    [draw_line]
  592.  
  593.         ; left border
  594.         pop     ebx
  595.         push    edx
  596.         mov     edx, eax
  597.         shr     edx, 16
  598.         mov     ax, dx
  599.         mov     edx, ebx
  600.         shr     edx, 16
  601.         mov     bx, dx
  602.         add     bx, [esp + 4 + 0]
  603.         pop     edx
  604.         add     ebx, 0x00010000
  605.         dec     bx
  606.         call    [draw_line]
  607.  
  608.         ; right border
  609.         mov     dx, [esp + 4]
  610.         add     ax, dx
  611.         shl     edx, 16
  612.         add     eax, edx
  613.         call    [draw_line]
  614.  
  615.         pop     ecx ebx
  616.  
  617.         popad
  618.         ret
  619.