Subversion Repositories Kolibri OS

Rev

Rev 895 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
895 barsuk 1
Общесистемный буфер обмена для ОС Колибри.
2
Информация для разработчиков.
3
 
4
Кратко: Буфер реализован через процесс-демон и IPC-сообщения.
5
Для проверки нужно запустить @clip(демон) и
6
(cliptest и доску отладки) или test2(можно несколько).
7
 
8
1. Демон @clip и его команды.
9
 
10
Демон @clip реализован как процесс, не создающий окон (зачем они ему),
11
а только слушающий IPC-сообщения. Демон поддерживает до 16 (MAX_FORMAT) буферов для
12
различных форматов данных, и до 16,7 Мб (MAX_SIZE) данных в каждом буфере
13
(память отводится динамически).
14
Id формата данных - число от 0 до 65534 (значение 65535 зарезервировано).
15
 
16
При запуске демон завершает все другие процессы @clip.
17
 
18
Команды, передаваемые демону, имеют формат:
19
 
20
[ Cmd: word | Format: word | Reserved: Dword | Data: ...]
21
 
22
где Cmd - код команды,
23
Format - id формата данных,
24
Reserved - что угодно (не используется),
25
и Data - данные, смысл которых зависит от команды.
26
 
27
Демон воспринимает следующие команды:
28
 
29
Код 1. Set Size. Указать необходимый размер буфера для приема данных. По этой
30
команде демон при необходимости расширяет свой буфер для IPC-сообщений
31
(способа уменьшить буфер в текущей реализации нет).
32
Параметр Data: 1 Dword, содержащий размер данных для передачи.
33
Длина команды: 12 байт.
34
 
35
Код 2. Set. Передача данных. По этой команде данные копируются в память демона.
36
Параметр Data: данные, которые нужно скопировать.
37
Длина команды: 8 + (длина данных) байт.
38
 
39
Код 3. Get Size. Получить размер данных, хранящихся в буфере с указанным id
40
формата. По этой команде демон отправляет ответное IPC-сообщение длиной 4
41
байта, содержащее размер данных в буфере. Если данные в буфере отсутствуют,
42
в сообщении указывается размер 0.
43
Длина команды: 8 байт.
44
 
45
Код 4. Get. Получить данные из буфера с указанным id формата. По этой команде
46
демон отправляет ответное IPC-сообщение нужной длины с данными из буфера.
47
Если данные в буфере отсутствуют, ответное сообщение не отправляется.
48
Длина команды: 8 байт.
49
 
50
Код 5. Delete. Очистить буфер с указанным id формата. Если указать
51
id формата = 0xFFFF, будут очищены все буферы.
52
Длина команды: 8 байт.
53
 
54
Исходный файл - @clip.asm. Если раскомментировать строчку
55
;define DEBUG TRUE
56
и закомментировать следующую, то демон начнет писать много буковок на доску
57
отладки, и по ним можно будет что-то понять о возникающих ошибках.
58
DEFAULT_SIZE - начальный размер IPC-буфера
59
MAX_SIZE - ограничение на буфер
60
MAX_FORMAT - число различных форматов, которые можно засунуть в демона
61
одновременно (а если больше, сглючит. Тоже надо пофиксить).
62
DELAY - задержка между попытками отправки сообщения, /100 сек.
63
ATTEMPT - количество попыток отправки сообщения занятому или не готовому
64
процессу.
65
 
66
 
67
2. clip.inc - набор функций для более высокоуровнего общения с демоном @clip.
68
Реализовано чтение буфера и запись в буфер.
69
 
70
Пример использования -  cliptest.asm (вывод на доску отладки) и
71
test2.asm.
72
 
73
При использовании clip.inc необходимо указать следующие значения (числа,
74
естественно, могут быть другие):
75
DEFAULT_MASK = 7	; Маска событий (см. функцию 40) по умолчанию для
76
			; текущего потока. Нужна, чтобы после приема
77
			; IPC-сообщения (когда маска меняется на 01000000b)
78
			; восстановить старую маску (а получить маску ХЗ как).
79
 
80
SEND_DELAY = 10		; пауза между попытками при отправке сообщения демону
81
 
82
RECV_DELAY = 100	; время ожидания ответа от демона (если за это время
83
			; не пришел ответ, то ошибка)
84
			; время - в сотых секунды (как для функции 5).
85
 
86
ATTEMPT = 5		; количество попыток отправки сообщения, если демон
87
			; занят
88
 
89
После включения clip.inc становятся доступными функции:
90
 
91
clipboard_init() - поиск процесса @clip. Эту функцию
92
можно вызывать многократно (например, если демон не нашелся или был
93
перезапущен), но 1 раз вызвать обязательно нужно.
94
Возвращает 1 при успехе и 0 при неудаче (не найден демон).
95
 
96
clipboard_write(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
97
ax (слово) - id формата ) - запись данных в буфер обмена.
98
Выполняет команды 1 и 2. Возвращает 1 при успехе и 0 при неудаче
99
(причины бывают разные: демон не был найден или занят и т.д.).
100
 
101
clipboard_read(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
102
ax (слово) - id формата ) - чтение данных из буфера обмена. Выполняет
103
команды 3 и 4. Возвращает в eax 1 при успехе, -1 при нехватке места в
104
буфере-приемнике(который в этом случае не меняется) и 0 при прочих ошибках.
105
В edx(при eax=1 или -1) возвращается действительный размер данных в буфере.
106
 
107
Замечание. Если приложение использует входящие IPC не только для работы с
108
буфером обмена, следует обрабатывать сообщения демона @clip вручную, т.к.
109
иначе может возникнуть такая ситуация: сообщение от другого приложения
110
попадет в буфер этого приложения для сообщений от демона буфера,
111
и будет проигнорировано.
112
 
113
Также можно использовать(после вызова clipboard_init) следующие функции более
114
низкого уровня:
115
_ipc_send (esi указывает на обычный буфер, edx - количество байт).
116
Отправляет IPC-сообщение демону. Отличие от функции 60/2 в том, что _ipc_send
117
повторяет несколько (точнее, ATTEMPTS) раз попытку отправки, если буфер демона
118
занят (код 2) или переполнен (код 3), с паузой в SEND_DELAY/100 секунд.
119
Возвращает 1 при успехе, 0 при ошибке.
120
 
121
_ipc_recv(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
122
edx = маска событий потока по умолчанию).
123
Ждет сообщения от демона в течение RECV_DELAY/100 секунд. При успехе
124
результат сохраняется в esi.
125
Возвращает 1 при успехе, 0 при ошибке.
126
 
127
Формат буфера для работы с буфером обмена:
128
CLIP_BUFFER
129
(+0)	.size	dd	?	; здесь должен быть записан размер
130
				; собственно буфера (N)
131
				; при записи данных в буфер, если нужно
132
				; отправить меньшее количество байт,
133
				; временно запишите это количество сюда
134
				; (см. пример test2)
135
 
136
(+4)	.sys1	dd	?	; \  эти поля используются модулем clip.inc
137
				;  - для внутренних целей и не должны
138
(+8)	.sys2	dd	?       ; /  модифицироваться приложением
139
 
140
(+12)	.data	db	N dup(?); собственно данные буфера
141
 
142
Удачи в программировании и отладке!
143
 
144
; barsuk, 21.08.2008
145
 
146
 
147
 
148
 
149
@CLIP - дополнение. Версия 0.2.
150
 
151
Реализована возможность вставки текста в приложения, не поддерживающие работу
152
с @clip, при помощи функции 72.1. Однако, из-за особенностей реализации,
153
приложениям приходит код из edx, независимо от режима ввода(ascii/scancode).
154
Я решил, что большинство приложений, все же, юзают режим ascii, и поэтому
155
выбрал его и для @clip (а те приложения, которые используют режим скан-кодов,
156
получат неверный ввод).
157
Было бы неплохо внести изменения в ядро (хотя бы возможность узнать чужой
158
режим ввода).
159
 
160
Вставка осуществляется нажатием горячей клавиши ctrl-alt-v. Сначала нужно
161
запустить приложение, работающее с @clip (например, test2), и скопировать в
162
буфер с id = 1 (обычный текст) какой-либо текст.
163
 
164
Еще мысль: добавить в eolite (а хорошо бы и kfar) копирование в буфер
165
текущего пути и имени файла под курсором. Компиляция в fasm и сжатие в
166
kpack станет удобнее.
167
 
168
; 08.09.2008