Subversion Repositories Kolibri OS

Rev

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 --->