Rev 895 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
895 | barsuk | 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" |
||
1741 | dunkaist | 9 | include "../../../macros.inc" |
895 | barsuk | 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 |
||
1741 | dunkaist | 413 | ; <--- end of MenuetOS application --->--->--->--->><>--->--->--->---> |