Subversion Repositories Kolibri OS

Rev

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

  1. ; <--- description --->
  2. ; compiler:     FASM
  3. ; name:         Clipboard server/daemon
  4. ; version:      0.2
  5. ; author:       barsuk
  6.  
  7. ; <--- include all MeOS stuff --->
  8. include "lang.inc"
  9. include "..\..\..\MACROS.INC"
  10.  
  11. ; <--- start of MenuetOS application --->
  12. MEOS_APP_START
  13.  
  14. ;define DEBUG TRUE
  15. define DEBUG FALSE
  16. include "bdebug.inc"
  17.  
  18. DEFAULT_SIZE = 0x10010  ; 64K + size of headers
  19. MAX_SIZE = 0x01000000   ; 16 M
  20. MAX_FORMAT = 16
  21. DELAY = 10              ; 1/10 sec between sending attempts
  22. ATTEMPT = 5             ; number of sending attempts
  23.  
  24.  
  25. ; <--- start of code --->
  26. CODE
  27.  
  28.         ; ¢®-¯¥à¢ëå, ­ ¤® 㡨âì ¢á¥ @clip, ª ª¨¥ ­ ©¤ãâáï:
  29.         ; ¤¥¬®­ ¡ãä¥à  ®¡¬¥­  ¤®«¦¥­ ¡ëâì ⮫쪮 ®¤¨­!
  30.         ; ¨ ¨¬ ®ª ¦¥âáï á ¬ë© ¬®«®¤®© ¨§ ¤¥¬®­®¢...
  31.  
  32.         mov     ecx, 2  ; ¯¥à¢ë© ­®¬¥à á«®â  ¤«ï ¯à®¢¥àª¨
  33.         mov     ebp, info
  34.         mov     ebx, ebp
  35.         mov     edx, 18
  36. .next_process:
  37.         mov     eax, 9
  38.         int     0x40
  39.         cmp     dword [ebx + 10], '@CLI'
  40.         jnz     .differ
  41.         cmp     byte [ebx + 14], 'P'
  42.         jnz     .differ
  43. .similar:
  44.         xchg    eax, edx
  45.         mov     ebx, 2
  46.         int     0x40
  47.         mov     ebx, ebp
  48.         xchg    eax, edx
  49. .differ:
  50.         inc     ecx
  51.         cmp     ecx, eax
  52.         jae     .done           ; process not found
  53.         jmp     .next_process
  54.  
  55. .done:
  56.         mov     eax, 68                 ; init heap
  57.         mov     ebx, 11
  58.         int     0x40
  59.  
  60.         mov     eax, 66                 ; set hotkey: Ctrl-Alt-V
  61.         mov     ebx, 4
  62.         mov     ecx, 47
  63.         mov     edx, 0x110                  ; 0x110
  64.         int     0x40
  65. print "set hot key (1 bad)"
  66. pregs
  67.  
  68.         mov     ebp, DEFAULT_SIZE
  69.  
  70.         mov     eax, 68                 ; get memory for buffer
  71.         mov     ebx, 12
  72.         mov     ecx, ebp
  73.         int     0x40
  74.         mov     esi, IPC_buffer
  75.         mov     [esi], eax
  76.  
  77.         mov     eax, 60                 ; define buffer for IPC
  78.         mov     ebx, 1
  79.         mov     ecx, [esi]
  80.         mov     edx, ebp
  81.         int     0x40
  82.  
  83.         mov     eax, 40
  84.         mov     ebx, 01000010b          ;
  85.         int     0x40
  86.  
  87. wait_event:                             ; main cycle
  88.         mov     eax, [IPC_buffer]
  89.         mov     dword [eax], 0          ; unlock buffer
  90.         mov     dword [eax + 4], 8
  91.  
  92.         mov     eax, 10                 ; wait
  93.         int     0x40
  94. print "event"
  95. pregs
  96.  
  97.         ;dec    eax
  98.         ;dec    eax
  99.         cmp     eax, 2
  100.         jnz     ipc_event
  101.  
  102. print "hotkey"
  103.  
  104.         mov     eax, 2
  105.         int     0x40
  106. pregs
  107.         cmp     ah, 47            ; "v" up
  108.         jnz     wait_event
  109.  
  110. print "hotkey v up"
  111.                                         ; it is hotkey
  112.         mov     eax, 1
  113.         mov     ebx, eax
  114.         call    find_format
  115. pregs
  116.         cmp     eax, -1
  117.         jz      wait_event
  118.         mov     esi, [data_buffer + eax * 4]
  119.         mov     edi, [data_size + eax * 4]
  120.         mov     ecx, 2
  121. print "ping"
  122. .next:
  123.         mov     eax, 72
  124.         movzx   edx, byte [esi]
  125.         int     0x40                    ; here we should pause if eax = 1
  126. pregs
  127.  
  128.         inc     esi
  129.         dec     edi
  130.         jnz     .next
  131.         jmp     wait_event
  132.  
  133. ipc_event:
  134.  
  135. ;       we get an IPC message
  136.  
  137. print "recv. "
  138.  
  139.         mov     eax, [IPC_buffer]
  140.         mov     dword [eax], 1          ; lock buffer
  141.         mov     dword [eax + 4], 8
  142.  
  143. dph1   dword [eax]                     ; lock
  144. dph1   dword [eax + 4]                 ; current used size
  145. dph1   dword [eax + 8]                 ; pid
  146. dph1   dword [eax + 12]                ; len
  147. print ""
  148. dph1   dword [eax + 16]                ; cmd << 16 | fmt
  149. dph1   dword [eax + 20]
  150. dph1   dword [eax + 24]
  151.  
  152.         mov     ebx, [eax + 8 + 4]
  153.         cmp     ebx, 8
  154.         jb      wait_event              ; all my messages have 8-byte header
  155.                                         ; so ignore this one
  156.  
  157.         movzx   ecx, word [eax + 8 + 8] ; command
  158.         cmp     ecx, 1
  159.         jz      command_setsize
  160.         cmp     ecx, 2
  161.         jz      command_set
  162.         cmp     ecx, 3
  163.         jz      command_getsize
  164.         cmp     ecx, 4
  165.         jz      command_get
  166.         cmp     ecx, 5
  167.         jz      command_delete
  168.         jmp     wait_event              ; unrecognised command
  169.  
  170. command_setsize:
  171.  
  172. ; the only thing we really need to do here is to grow IPC buffer
  173. ; no changes are done to real buffer of chosen format
  174.  
  175. ; the bad thing is that IPC buffer grows and never becomes less.
  176. ; i want to fix this in the next version.
  177.  
  178. print "set size"
  179.  
  180.         mov     esi, [IPC_buffer_size]
  181.         mov     ecx, [eax + 24]         ; size
  182.         add     ecx, 0x18               ; for headers
  183. ;pregs
  184.         cmp     esi, ecx
  185.         jae     wait_event
  186. print "ipc buffer resize from esi to ecx"
  187. pregs
  188.  
  189.         mov     ebp, MAX_SIZE   ; sort of protection. forbid transfer of more
  190.         cmp     ecx, ebp        ; than 16,7 Mb of data through buffer
  191.         jbe     not_much
  192.         mov     ecx, ebp
  193.  
  194. not_much:
  195.         xchg    eax, edi        ; edx := [IPC_buffer]
  196.         add     ecx, 0x18       ; for headers
  197.  
  198.         mov     [IPC_buffer_size], ecx
  199.         mov     eax, 68
  200.         mov     ebx, 12
  201.         int     0x40            ; get memory
  202. print "get mem for new buf, eax"
  203. pregs
  204.         mov     [IPC_buffer], eax
  205.  
  206.         mov     dword [eax + 4], 8
  207.         mov     edx, ecx
  208.         mov     ecx, eax
  209.         mov     eax, 60
  210.         mov     ebx, 1
  211.         int     0x40            ; make it IPC buffer
  212.  
  213.         mov     ecx, edi
  214.         mov     eax, 68
  215.         mov     ebx, 13
  216.         int     0x40            ; free old IPC buffer
  217.  
  218.         jmp     wait_event
  219.  
  220. command_set:
  221. print "set"
  222.  
  223. ; here we put the data transfered to us to one of internal buffers
  224.  
  225. ;;;outs eax + 0x18
  226.  
  227.         movzx   eax, word [eax + 18]            ; format id
  228.         call    find_format
  229.         cmp     eax, -1
  230.         jz      new_format
  231.         mov     edx, eax
  232.  
  233.         ; free old buffer of this format
  234.  
  235.         mov     ecx, [data_buffer + edx * 4]
  236.         mov     eax, 68
  237.         mov     ebx, 13
  238.         int     0x40
  239.         jmp     set_buffer
  240.  
  241. new_format:
  242.         mov     eax, data_count         ; allocate a buffer
  243.         mov     edx, [eax]
  244.         inc     dword [eax]             ; no protection, no checks. very bad :(
  245. set_buffer:
  246.         mov     eax, [IPC_buffer]
  247.         mov     ecx, dword [eax + 12]
  248.         sub     ecx, 8                  ; get length of data itself
  249.                                         ; subtract size of my headers
  250. ;pregs
  251.         mov     [data_size + edx * 4], ecx      ; save length of data
  252.  
  253.         mov     eax, 68
  254.         mov     ebx, 12
  255.         int     0x40
  256.         mov     [data_buffer + edx * 4], eax
  257.  
  258. ; copy data from IPC to new buffer
  259.         mov     esi, [IPC_buffer]
  260.         mov     ebp, esi
  261.         add     esi, 24                 ; start of data
  262.         mov     edi, eax
  263.         rep     movsb                   ; oh, me knows that it's bad
  264.  
  265.         mov     eax, ebp
  266.         movzx   ecx, word [eax + 18]            ; format id
  267.         mov     [data_format + edx * 4], ecx
  268.  
  269.                 ; debug
  270. ;       print   "set debug"
  271. ;       mov     eax, [data_buffer + edx * 4]
  272. ;       mov     ebx, [data_size + edx * 4]
  273. ;       mov     ecx, [data_format + edx * 4]
  274. ;       pregs
  275.  
  276.         jmp     wait_event
  277.  
  278. command_delete:
  279.         movzx   eax, word [eax + 18]            ; format id
  280.         cmp     eax, -1
  281.         jz      command_clear
  282.         call    find_format
  283.         cmp     eax, -1
  284.         jz      wait_event
  285.         mov     ecx, [data_buffer + eax * 4]
  286.         mov     [data_format + eax * 4], 0
  287.         mov     eax, 68
  288.         mov     ebx, 13
  289.         int     0x40
  290.         jmp     wait_event
  291.  
  292. command_clear:
  293.         mov     eax, 68
  294.         mov     ebx, 13
  295.         mov     edx, data_buffer
  296. .next:
  297.         mov     ecx, [edx]
  298.         jecxz   .nofree
  299.         int     0x40
  300. .nofree:
  301.         mov     [edx + data_size - data_buffer], 0
  302.         add     edx, 4
  303.         cmp     edx, data_format
  304.         jnae    .next
  305.         jmp     wait_event
  306.  
  307. command_getsize:
  308.  
  309. print "get size"
  310.  
  311.         ; we should send reply, containing size of data with chosen format id
  312.         movzx   eax, word [eax + 18]            ; format id
  313.         mov     esi, 4
  314.         call    find_format
  315. ;pregs
  316.         cmp     eax, -1
  317.         jz      zero_size
  318.  
  319.         lea     edx, [data_size + eax * 4]
  320.         mov     eax, [edx]
  321.         jmp     send_getsize
  322. zero_size:
  323.         mov     edx, dw_zero    ; send 0 to indicate that the buffer is empty
  324. send_getsize:
  325.         jmp     send_msg
  326.  
  327. command_get:
  328. print "get"
  329.  
  330. ; we need to send the data
  331.  
  332.         ; [:||||:]
  333.  
  334.         movzx   eax, word [eax + 18]            ; format id
  335.         call    find_format
  336.         cmp     eax, -1
  337.         jz      wait_event
  338.         mov     edi, eax                        ;   ­¥ä¨£
  339.  
  340.         mov     edx, [data_buffer + edi * 4]
  341.         mov     esi, [data_size + edi * 4]
  342.         ;jmp    send_msg
  343.  
  344. send_msg:
  345.  
  346.         ; for debugging
  347. ;       mov     eax, 5
  348. ;       mov     ebx, DELAY*5
  349. ;       int     0x40
  350.  
  351.         mov     ebp, ATTEMPT            ; number of attempts to send
  352.         mov     eax, [IPC_buffer]
  353.         mov     ecx, [eax + 8]          ; sender PID
  354.         mov     eax, 60
  355.         mov     ebx, 2
  356.         int     0x40
  357. print "send data result eax"
  358. pregs
  359.         cmp     eax, 2
  360.         jz      .wait
  361.         cmp     eax, 3                  ; it is strange..
  362.         jz      .wait                   ; maybe he needs time to resize his buf
  363.         jmp     wait_event
  364. .wait:
  365.         dec     ebp
  366.         jz      wait_event
  367.         mov     eax, 5                  ; sleep a bit
  368.         mov     ebx, DELAY
  369.         int     0x40
  370.         jmp     send_msg
  371.  
  372.  
  373. find_format:                    ; small function returning number of format
  374.  
  375. ;print "find format"
  376.         push    ebx
  377.         mov     ebx, eax        ; format id
  378.         and     ebx, 0xffff     ; it is word
  379.         xor     eax, eax
  380. next:
  381.         cmp     [data_format + eax * 4], ebx
  382.         jz      found
  383.         inc     eax
  384.         cmp     eax, MAX_FORMAT
  385.         jb      next
  386. not_found:
  387.         or      eax, -1
  388. found:
  389. ;pregs
  390.         pop     ebx
  391.         ret
  392.  
  393. ; <--- initialised data --->
  394. DATA
  395.         IPC_buffer      dd      0
  396.         IPC_buffer_size dd      DEFAULT_SIZE            ; initially 64K
  397.  
  398.         info            db      1024 dup(0)             ; for process info
  399.  
  400.         data_buffer     dd      MAX_FORMAT dup(0)       ; buffer for some format
  401.                                                         ; (256 formats max)
  402.         data_format     dd      MAX_FORMAT dup(0)       ; format id
  403.         data_size       dd      MAX_FORMAT dup(0)       ; size of buffer
  404.         data_count      dd      0                       ; number of formats used
  405.         dw_zero         dd      0                       ; used to tell that
  406.                                                         ; we don't have a format
  407.  
  408. ; <--- uninitialised data --->
  409. UDATA
  410.  
  411.  
  412. MEOS_APP_END
  413. ; <--- end of MenuetOS application --->