Общесистемный буфер обмена для ОС Колибри. 
Информация для разработчиков.

Кратко: Буфер реализован через процесс-демон и IPC-сообщения.
Для проверки нужно запустить @clip(демон) и 
(cliptest и доску отладки) или test2(можно несколько).

1. Демон @clip и его команды.

Демон @clip реализован как процесс, не создающий окон (зачем они ему), 
а только слушающий IPC-сообщения. Демон поддерживает до 16 (MAX_FORMAT) буферов для
различных форматов данных, и до 16,7 Мб (MAX_SIZE) данных в каждом буфере 
(память отводится динамически).
Id формата данных - число от 0 до 65534 (значение 65535 зарезервировано).

При запуске демон завершает все другие процессы @clip.

Команды, передаваемые демону, имеют формат:

[ Cmd: word | Format: word | Reserved: Dword | Data: ...]

где Cmd - код команды,
Format - id формата данных,
Reserved - что угодно (не используется),
и Data - данные, смысл которых зависит от команды.

Демон воспринимает следующие команды:

Код 1. Set Size. Указать необходимый размер буфера для приема данных. По этой
команде демон при необходимости расширяет свой буфер для IPC-сообщений
(способа уменьшить буфер в текущей реализации нет).
Параметр Data: 1 Dword, содержащий размер данных для передачи.
Длина команды: 12 байт.

Код 2. Set. Передача данных. По этой команде данные копируются в память демона.
Параметр Data: данные, которые нужно скопировать.
Длина команды: 8 + (длина данных) байт.

Код 3. Get Size. Получить размер данных, хранящихся в буфере с указанным id
формата. По этой команде демон отправляет ответное IPC-сообщение длиной 4
байта, содержащее размер данных в буфере. Если данные в буфере отсутствуют,
в сообщении указывается размер 0.
Длина команды: 8 байт.

Код 4. Get. Получить данные из буфера с указанным id формата. По этой команде
демон отправляет ответное IPC-сообщение нужной длины с данными из буфера.
Если данные в буфере отсутствуют, ответное сообщение не отправляется.
Длина команды: 8 байт.

Код 5. Delete. Очистить буфер с указанным id формата. Если указать 
id формата = 0xFFFF, будут очищены все буферы.
Длина команды: 8 байт.

Исходный файл - @clip.asm. Если раскомментировать строчку
;define DEBUG TRUE 
и закомментировать следующую, то демон начнет писать много буковок на доску
отладки, и по ним можно будет что-то понять о возникающих ошибках.
DEFAULT_SIZE - начальный размер IPC-буфера
MAX_SIZE - ограничение на буфер
MAX_FORMAT - число различных форматов, которые можно засунуть в демона
одновременно (а если больше, сглючит. Тоже надо пофиксить).
DELAY - задержка между попытками отправки сообщения, /100 сек.
ATTEMPT - количество попыток отправки сообщения занятому или не готовому
процессу. 
 

2. clip.inc - набор функций для более высокоуровнего общения с демоном @clip.
Реализовано чтение буфера и запись в буфер.

Пример использования -  cliptest.asm (вывод на доску отладки) и
test2.asm.

При использовании clip.inc необходимо указать следующие значения (числа,
естественно, могут быть другие):
DEFAULT_MASK = 7	; Маска событий (см. функцию 40) по умолчанию для 
			; текущего потока. Нужна, чтобы после приема 
			; IPC-сообщения (когда маска меняется на 01000000b)
			; восстановить старую маску (а получить маску ХЗ как).

SEND_DELAY = 10		; пауза между попытками при отправке сообщения демону

RECV_DELAY = 100	; время ожидания ответа от демона (если за это время
			; не пришел ответ, то ошибка)
			; время - в сотых секунды (как для функции 5).

ATTEMPT = 5		; количество попыток отправки сообщения, если демон 
			; занят

После включения clip.inc становятся доступными функции:

clipboard_init() - поиск процесса @clip. Эту функцию
можно вызывать многократно (например, если демон не нашелся или был 
перезапущен), но 1 раз вызвать обязательно нужно.
Возвращает 1 при успехе и 0 при неудаче (не найден демон).

clipboard_write(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
ax (слово) - id формата ) - запись данных в буфер обмена. 
Выполняет команды 1 и 2. Возвращает 1 при успехе и 0 при неудаче 
(причины бывают разные: демон не был найден или занят и т.д.).

clipboard_read(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
ax (слово) - id формата ) - чтение данных из буфера обмена. Выполняет
команды 3 и 4. Возвращает в eax 1 при успехе, -1 при нехватке места в 
буфере-приемнике(который в этом случае не меняется) и 0 при прочих ошибках.
В edx(при eax=1 или -1) возвращается действительный размер данных в буфере.

Замечание. Если приложение использует входящие IPC не только для работы с 
буфером обмена, следует обрабатывать сообщения демона @clip вручную, т.к. 
иначе может возникнуть такая ситуация: сообщение от другого приложения
попадет в буфер этого приложения для сообщений от демона буфера, 
и будет проигнорировано.

Также можно использовать(после вызова clipboard_init) следующие функции более 
низкого уровня:
_ipc_send (esi указывает на обычный буфер, edx - количество байт).
Отправляет IPC-сообщение демону. Отличие от функции 60/2 в том, что _ipc_send
повторяет несколько (точнее, ATTEMPTS) раз попытку отправки, если буфер демона
занят (код 2) или переполнен (код 3), с паузой в SEND_DELAY/100 секунд.
Возвращает 1 при успехе, 0 при ошибке.

_ipc_recv(esi указывает на буфер в формате CLIP_BUFFER (см. далее),
edx = маска событий потока по умолчанию).
Ждет сообщения от демона в течение RECV_DELAY/100 секунд. При успехе
результат сохраняется в esi. 
Возвращает 1 при успехе, 0 при ошибке.

Формат буфера для работы с буфером обмена:
CLIP_BUFFER
(+0)	.size	dd	?	; здесь должен быть записан размер
				; собственно буфера (N)
				; при записи данных в буфер, если нужно
				; отправить меньшее количество байт,
				; временно запишите это количество сюда
				; (см. пример test2)

(+4)	.sys1	dd	?	; \  эти поля используются модулем clip.inc
				;  - для внутренних целей и не должны
(+8)	.sys2	dd	?       ; /  модифицироваться приложением

(+12)	.data	db	N dup(?); собственно данные буфера

Удачи в программировании и отладке!

; barsuk, 21.08.2008




@CLIP - дополнение. Версия 0.2.

Реализована возможность вставки текста в приложения, не поддерживающие работу 
с @clip, при помощи функции 72.1. Однако, из-за особенностей реализации, 
приложениям приходит код из edx, независимо от режима ввода(ascii/scancode). 
Я решил, что большинство приложений, все же, юзают режим ascii, и поэтому 
выбрал его и для @clip (а те приложения, которые используют режим скан-кодов, 
получат неверный ввод).
Было бы неплохо внести изменения в ядро (хотя бы возможность узнать чужой 
режим ввода).

Вставка осуществляется нажатием горячей клавиши ctrl-alt-v. Сначала нужно 
запустить приложение, работающее с @clip (например, test2), и скопировать в
буфер с id = 1 (обычный текст) какой-либо текст.

Еще мысль: добавить в eolite (а хорошо бы и kfar) копирование в буфер 
текущего пути и имени файла под курсором. Компиляция в fasm и сжатие в 
kpack станет удобнее.

; 08.09.2008