Subversion Repositories Kolibri OS

Rev

Rev 5580 | Rev 6031 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2015. 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: 6009 $
  10.  
  11. ;==============================================================================
  12. ;///// public functions ///////////////////////////////////////////////////////
  13. ;==============================================================================
  14.  
  15. button.MAX_BUTTONS = 4095
  16.  
  17. struct  SYS_BUTTON
  18.         pslot           dw ?
  19.         id_lo           dw ?
  20.         left            dw ?
  21.         width           dw ?
  22.         top             dw ?
  23.         height          dw ?
  24.         id_hi           dw ?
  25.                         dw ?
  26. ends
  27.  
  28. align 4
  29. ;------------------------------------------------------------------------------
  30. syscall_button: ;///// system function 8 //////////////////////////////////////
  31. ;------------------------------------------------------------------------------
  32. ;? Define/undefine GUI button object
  33. ;------------------------------------------------------------------------------
  34. ;; Define button:
  35. ;> ebx = pack[16(x), 16(width)]
  36. ;> ecx = pack[16(y), 16(height)]
  37. ;> edx = pack[8(flags), 24(button identifier)]
  38. ;>       flags bits:
  39. ;>          7 (31) = 0
  40. ;>          6 (30) = don't draw button
  41. ;>          5 (29) = don't draw button frame when pressed
  42. ;> esi = button color
  43. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  44. ;; Undefine button:
  45. ;> edx = pack[8(flags), 24(button identifier)]
  46. ;>       flags bits:
  47. ;>          7 (31) = 1
  48. ;------------------------------------------------------------------------------
  49.         ; do we actually need to undefine the button?
  50.         test    edx, 0x80000000
  51.         jnz     .remove_button
  52.  
  53.         ; do we have free button slots available?
  54.         mov     edi, [BTN_ADDR]
  55.         mov     eax, [edi]
  56.         cmp     eax, button.MAX_BUTTONS
  57.         jge     .exit
  58.  
  59.         ; does it have positive size? (otherwise it doesn't have sense)
  60.         or      bx, bx
  61.         jle     .exit
  62.         or      cx, cx
  63.         jle     .exit
  64.  
  65.         ; make coordinates clientbox-relative
  66.         push    eax
  67.         mov     eax, [current_slot]
  68.         rol     ebx, 16
  69.         add     bx, word[eax + APPDATA.wnd_clientbox.left]
  70.         rol     ebx, 16
  71.         rol     ecx, 16
  72.         add     cx, word[eax + APPDATA.wnd_clientbox.top]
  73.         rol     ecx, 16
  74.         pop     eax
  75.  
  76.         ; basic checks passed, define the button
  77.         push    ebx ecx edx
  78.         inc     eax
  79.         mov     [edi], ax
  80.         shl     eax, 4
  81.         add     edi, eax
  82.         ; NOTE: this code doesn't rely on SYS_BUTTON struct, please revise it
  83.         ;       if you change something
  84.         mov     ax, [CURRENT_TASK]
  85.         stosw
  86.         mov     ax, dx
  87.         stosw               ; button id number: bits 0-15
  88.         mov     eax, ebx
  89.         rol     eax, 16
  90.         stosd               ; x start | x size
  91.         mov     eax, ecx
  92.         rol     eax, 16
  93.         stosd               ; y start | y size
  94.         mov     eax, edx
  95.         shr     eax, 16
  96.         stosw               ; button id number: bits 16-31
  97.         pop     edx ecx ebx
  98.  
  99.         ; do we also need to draw the button?
  100.         test    edx, 0x40000000
  101.         jnz     .exit
  102.  
  103.         ; draw button body
  104.  
  105.         pushad
  106.  
  107.         ; calculate window-relative coordinates
  108.         movzx   edi, cx
  109.         shr     ebx, 16
  110.         shr     ecx, 16
  111.         mov     eax, [TASK_BASE]
  112.         add     ebx, [eax - twdw + WDATA.box.left]
  113.         add     ecx, [eax - twdw + WDATA.box.top]
  114.         mov     eax, ebx
  115.         inc     eax
  116.         shl     eax, 16
  117.         mov     ax, bx
  118.         add     ax, word[esp + 16]
  119.         dec     ax
  120.         mov     ebx, ecx
  121.         shl     ebx, 16
  122.         mov     bx, cx
  123.  
  124.         ; calculate initial color
  125.         mov     ecx, esi
  126.         cmp     [buttontype], 0
  127.         je      @f
  128.         call    button._.incecx2
  129.  
  130.         ; set button height counter
  131.     @@:
  132.         mov     edx, edi
  133.         add     ebx, 0x00010001
  134.         dec     edx
  135.  
  136.   .next_line:
  137.         call    button._.button_dececx
  138.         push    edi
  139.         xor     edi, edi
  140. ;        call    [draw_line]
  141.         call    __sys_draw_line
  142.         pop     edi
  143.         add     ebx, 0x00010001
  144.         dec     edx
  145.         jnz     .next_line
  146.  
  147.         popad
  148.  
  149.         ; draw button frame
  150.  
  151.         push    ebx ecx
  152.  
  153.         ; calculate window-relative coordinates
  154.         shr     ebx, 16
  155.         shr     ecx, 16
  156.         mov     eax, [TASK_BASE]
  157.         add     ebx, [eax - twdw + WDATA.box.left]
  158.         add     ecx, [eax - twdw + WDATA.box.top]
  159.  
  160.         ; top border
  161.         mov     eax, ebx
  162.         shl     eax, 16
  163.         mov     ax, bx
  164.         add     ax, [esp + 4]
  165.         mov     ebx, ecx
  166.         shl     ebx, 16
  167.         mov     bx, cx
  168.         push    ebx
  169.         xor     edi, edi
  170.         mov     ecx, esi
  171.         ; call    button._.incecx
  172. ;        call    [draw_line]
  173.         call    __sys_draw_line
  174.  
  175.         ; light line under top border
  176.         add     ebx, 0x00010001
  177.         mov     ecx, esi
  178.         call    button._.incecx
  179.         call    __sys_draw_line
  180.         sub     ebx, 0x00010001
  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.         call    __sys_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._.dececx ; button._.incecx
  204. ;        call    [draw_line]
  205.         dec     ebx
  206.         call    __sys_draw_line
  207.  
  208.         ; right border
  209.         mov     dx, [esp + 4]
  210.         add     ax, dx
  211.         shl     edx, 16
  212.         add     eax, edx
  213.         add     ebx, 0x00010000
  214.         mov     ecx, esi
  215.         call    button._.dececx
  216. ;        call    [draw_line]
  217.         call    __sys_draw_line
  218.  
  219.         pop     ecx ebx
  220.  
  221.   .exit:
  222.         ret
  223.  
  224. ; FIXME: mutex needed
  225. syscall_button.remove_button:
  226.         and     edx, 0x00ffffff
  227.         mov     edi, [BTN_ADDR]
  228.         mov     ebx, [edi]
  229.         inc     ebx
  230.         imul    esi, ebx, sizeof.SYS_BUTTON
  231.         add     esi, edi
  232.         xor     ecx, ecx
  233.         add     ecx, -sizeof.SYS_BUTTON
  234.         add     esi, sizeof.SYS_BUTTON
  235.  
  236.   .next_button:
  237.         dec     ebx
  238.         jz      .exit
  239.  
  240.         add     ecx, sizeof.SYS_BUTTON
  241.         add     esi, -sizeof.SYS_BUTTON
  242.  
  243.         ; does it belong to our process?
  244.         mov     ax, [CURRENT_TASK]
  245.         cmp     ax, [esi + SYS_BUTTON.pslot]
  246.         jne     .next_button
  247.  
  248.         ; does the identifier match?
  249.         mov     eax, dword[esi + SYS_BUTTON.id_hi - 2]
  250.         mov     ax, [esi + SYS_BUTTON.id_lo]
  251.         and     eax, 0x00ffffff
  252.         cmp     edx, eax
  253.         jne     .next_button
  254.  
  255.         ; okay, undefine it
  256.         push    ebx
  257.         mov     ebx, esi
  258.         lea     eax, [esi + sizeof.SYS_BUTTON]
  259.         call    memmove
  260.         dec     dword[edi]
  261.         add     ecx, -sizeof.SYS_BUTTON
  262.         pop     ebx
  263.         jmp     .next_button
  264.  
  265.   .exit:
  266.         ret
  267.  
  268. align 4
  269. ;------------------------------------------------------------------------------
  270. sys_button_activate_handler: ;/////////////////////////////////////////////////
  271. ;------------------------------------------------------------------------------
  272. ;? <description>
  273. ;------------------------------------------------------------------------------
  274. ;> eax = pack[8(process slot), 24(button id)]
  275. ;> ebx = pack[16(button x coord), 16(button y coord)]
  276. ;> cl = mouse button mask this system button was pressed with
  277. ;------------------------------------------------------------------------------
  278.         call    button._.find_button
  279.         or      eax, eax
  280.         jz      .exit
  281.  
  282.         mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]
  283.         call    button._.negative_button
  284.  
  285.   .exit:
  286.         ret
  287.  
  288. align 4
  289. ;------------------------------------------------------------------------------
  290. sys_button_deactivate_handler: ;///////////////////////////////////////////////
  291. ;------------------------------------------------------------------------------
  292. ;? <description>
  293. ;------------------------------------------------------------------------------
  294. ;> eax = pack[8(process slot), 24(button id)]
  295. ;> ebx = pack[16(button x coord), 16(button y coord)]
  296. ;> cl = mouse button mask this system button was pressed with
  297. ;------------------------------------------------------------------------------
  298.         call    button._.find_button
  299.         or      eax, eax
  300.         jz      .exit
  301.  
  302.         mov     ebx, dword[eax + SYS_BUTTON.id_hi - 2]
  303.         call    button._.negative_button
  304.  
  305.   .exit:
  306.         ret
  307.  
  308. align 4
  309. ;------------------------------------------------------------------------------
  310. sys_button_perform_handler: ;//////////////////////////////////////////////////
  311. ;------------------------------------------------------------------------------
  312. ;? <description>
  313. ;------------------------------------------------------------------------------
  314. ;> eax = pack[8(process slot), 24(button id)]
  315. ;> ebx = pack[16(button x coord), 16(button y coord)]
  316. ;> cl = mouse button mask this system button was pressed with
  317. ;------------------------------------------------------------------------------
  318.         shl     eax, 8
  319.         mov     al, cl
  320.         movzx   ebx, byte[BTN_COUNT]
  321.         mov     [BTN_BUFF + ebx * 4], eax
  322.         inc     bl
  323.         mov     [BTN_COUNT], bl
  324.         ret
  325.  
  326. ;==============================================================================
  327. ;///// private functions //////////////////////////////////////////////////////
  328. ;==============================================================================
  329.  
  330. ;------------------------------------------------------------------------------
  331. button._.find_button: ;////////////////////////////////////////////////////////
  332. ;------------------------------------------------------------------------------
  333. ;? Find system button by specified process slot, id and coordinates
  334. ;------------------------------------------------------------------------------
  335. ;> eax = pack[8(process slot), 24(button id)] or 0
  336. ;> ebx = pack[16(button x coord), 16(button y coord)]
  337. ;------------------------------------------------------------------------------
  338. ;< eax = pointer to SYS_BUTTON struct or 0
  339. ;------------------------------------------------------------------------------
  340.         push    ecx edx esi edi
  341.  
  342.         mov     edx, eax
  343.         shr     edx, 24
  344.         and     eax, 0x0ffffff
  345.  
  346.         mov     edi, [BTN_ADDR]
  347.         mov     ecx, [edi]
  348.         imul    esi, ecx, sizeof.SYS_BUTTON
  349.         add     esi, edi
  350.         inc     ecx
  351.         add     esi, sizeof.SYS_BUTTON
  352.  
  353.   .next_button:
  354.         dec     ecx
  355.         jz      .not_found
  356.  
  357.         add     esi, -sizeof.SYS_BUTTON
  358.  
  359.         ; does it belong to our process?
  360.         cmp     dx, [esi + SYS_BUTTON.pslot]
  361.         jne     .next_button
  362.  
  363.         ; does id match?
  364.         mov     edi, dword[esi + SYS_BUTTON.id_hi - 2]
  365.         mov     di, [esi + SYS_BUTTON.id_lo]
  366.         and     edi, 0x0ffffff
  367.         cmp     eax, edi
  368.         jne     .next_button
  369.  
  370.         ; does coordinates match?
  371.         mov     edi, dword[esi + SYS_BUTTON.left - 2]
  372.         mov     di, [esi + SYS_BUTTON.top]
  373.         cmp     ebx, edi
  374.         jne     .next_button
  375.  
  376.         ; okay, return it
  377.         mov     eax, esi
  378.         jmp     .exit
  379.  
  380.   .not_found:
  381.         xor     eax, eax
  382.  
  383.   .exit:
  384.         pop     edi esi edx ecx
  385.         ret
  386.  
  387. ;------------------------------------------------------------------------------
  388. button._.dececx: ;/////////////////////////////////////////////////////////////
  389. ;------------------------------------------------------------------------------
  390. ;? <description>
  391. ;------------------------------------------------------------------------------
  392.         sub     cl, 0x20
  393.         jnc     @f
  394.         xor     cl, cl
  395.     @@:
  396.         sub     ch, 0x20
  397.         jnc     @f
  398.         xor     ch, ch
  399.     @@:
  400.         rol     ecx, 16
  401.         sub     cl, 0x20
  402.         jnc     @f
  403.         xor     cl, cl
  404.     @@:
  405.         rol     ecx, 16
  406.         ret
  407.  
  408. ;------------------------------------------------------------------------------
  409. button._.incecx: ;/////////////////////////////////////////////////////////////
  410. ;------------------------------------------------------------------------------
  411. ;? <description>
  412. ;------------------------------------------------------------------------------
  413.         add     cl, 0x20
  414.         jnc     @f
  415.         or      cl, -1
  416.     @@:
  417.         add     ch, 0x20
  418.         jnc     @f
  419.         or      ch, -1
  420.     @@:
  421.         rol     ecx, 16
  422.         add     cl, 0x20
  423.         jnc     @f
  424.         or      cl, -1
  425.     @@:
  426.         rol     ecx, 16
  427.         ret
  428.  
  429. ;------------------------------------------------------------------------------
  430. button._.incecx2: ;////////////////////////////////////////////////////////////
  431. ;------------------------------------------------------------------------------
  432. ;? <description>
  433. ;------------------------------------------------------------------------------
  434.         add     cl, 0x14
  435.         jnc     @f
  436.         or      cl, -1
  437.     @@:
  438.         add     ch, 0x14
  439.         jnc     @f
  440.         or      ch, -1
  441.     @@:
  442.         rol     ecx, 16
  443.         add     cl, 0x14
  444.         jnc     @f
  445.         or      cl, -1
  446.     @@:
  447.         rol     ecx, 16
  448.         ret
  449.  
  450. ;------------------------------------------------------------------------------
  451. button._.button_dececx: ;//////////////////////////////////////////////////////
  452. ;------------------------------------------------------------------------------
  453. ;? <description>
  454. ;------------------------------------------------------------------------------
  455.         cmp     [buttontype], 1
  456.         jne     .finish
  457.  
  458.         push    eax
  459.         mov     al, 1
  460.         cmp     edi, 20
  461.         jg      @f
  462.         mov     al, 2
  463.  
  464.     @@:
  465.         sub     cl, al
  466.         jnc     @f
  467.         xor     cl, cl
  468.     @@:
  469.         sub     ch, al
  470.         jnc     @f
  471.         xor     ch, ch
  472.     @@:
  473.         rol     ecx, 16
  474.         sub     cl, al
  475.         jnc     @f
  476.         xor     cl, cl
  477.     @@:
  478.         rol     ecx, 16
  479.  
  480.         pop     eax
  481.  
  482.   .finish:
  483.         ret
  484.  
  485. ;------------------------------------------------------------------------------
  486. button._.negative_button: ;////////////////////////////////////////////////////
  487. ;------------------------------------------------------------------------------
  488. ;? Invert system button border
  489. ;------------------------------------------------------------------------------
  490.         ; if requested, do not display button border on press.
  491.         test    ebx, 0x20000000
  492.         jnz     .exit
  493.  
  494.         pushad
  495.  
  496.         xchg    esi, eax
  497.  
  498.         movzx   ecx, [esi + SYS_BUTTON.pslot]
  499.         shl     ecx, 5
  500.         add     ecx, window_data
  501.  
  502.         mov     eax, dword[esi + SYS_BUTTON.left]
  503.         mov     ebx, dword[esi + SYS_BUTTON.top]
  504.         add     eax, [ecx + WDATA.box.left]
  505.         add     ebx, [ecx + WDATA.box.top]
  506.         push    eax ebx
  507.         pop     edx ecx
  508.         rol     eax, 16
  509.         rol     ebx, 16
  510.         add     ax, cx
  511.         add     bx, dx
  512.  
  513.         mov     esi, 0x01000000
  514.         call    draw_rectangle.forced
  515.  
  516.         popad
  517.  
  518.   .exit:
  519.         ret
  520.