- Move source code from `trunk` into root directory. - Update build files and ASM include paths. - Note: Line endings standardised from `CRLF` > `LF`, so best to view diffs with whitespace changes hidden.
168 lines
6.9 KiB
Plaintext
168 lines
6.9 KiB
Plaintext
Общесистемный буфер обмена для ОС Колибри.
|
||
Информация для разработчиков.
|
||
|
||
Кратко: Буфер реализован через процесс-демон и 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 |