Page 7 of 13
Re: Общесистемный буфер обмена
Posted: Fri Dec 07, 2012 11:14 pm
by Serge
johnfound
Прозрачно может быть только в одном случае - гребём из буфера всё сразу не разбираясь с размером данных. Но в этом случае место под данные должно выделять ядро, потому что только оно знает размер. Выделение памяти ядром немного громоздкая операция.
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 1:13 am
by johnfound
Ну вот предлагаю так:
Code: Select all
OpenClipboard
Read/Write/Clear/GetInfoClipboard
CloseClipboard
OpenClipboard - блокирует буфер только для этого приложения. CloseClipboard - разблокирует. Только надо чтобы было максимальное время в пределах которого можно вызывать остальные функции. Иначе ядро закрывает буфер и на запросы приложения отвечает ошибкой.
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 9:23 am
by Serge
Можно и без блокировки для чтения.
Приложение создаёт буфер 68.12 и передаёт ядру указатель и размер. Ядро при необходимости увеличит размер буфера или создаст новый. Когда буфер будет ненужен приложение освободит его. Надо только учитывать что после вызова функции адрес буфера может поменяться.
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 11:15 am
by johnfound
Serge, чем проще (для использования), тем лучше.
Использовать 68.11 не стоит - это ограничит использование буфера обмена только для приложения которые не используют ф.64
Лучше блокировать буфер явно. Кстати, в Windows именно так и сделано и работает вполне хорошо.
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 12:43 pm
by Serge
Чёртов файрфокс упал и убил стену текста
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 6:34 pm
by 0CodErr
А если так:
Подфункция 2: Прочитать из буфера
ebx = 2
ecx = размер буфера-приёмника
edx = тип данных
edi = указатель на буфер-приёмник
Если в буфере есть запрашиваемый тип данных, то
скопировать данные
вернуть успех
Иначе
вернуть ошибку.
Количество одновременно хранимых данных разных типов
ядро определяет в зависимости от размера этих данных
и размера свободной памяти.
Приложение создаёт буфер с запасом в зависимости от данных, так как
приложение знает, с данными какого размера оно хочет и может работать.
Если же всё-таки размер буфера-приёмника окажется меньше, чем размер данных, то
вернуть ошибку и размер данных.
Если приложение захочет, то оно сделает новый запрос с учётом этого размера.
Re: Общесистемный буфер обмена
Posted: Sat Dec 08, 2012 11:58 pm
by Serge
johnfound
ф64. не позволяет загружать длл и другие ограничения у неё есть. К тому же она легко эмулируется набором 68.12 и 68.26.
read_clipboard:
in:
eax = ?
ebx = ?
ecx = buffer
edx = format
out:
eax = size
edx = buffer
Самый простой вариант > 90% случаев
Code: Select all
/* somwhere in .bss */
void *buffer;
int size;
/* main code */
buffer = read_clipboard(buffer, &size, format);
if( size != 0 )
{
profit();
}
Bce операции с блокировками и памятью выполняет ядро. Если приложение передаёт ненулевой указатель то буфер должен быть создан 68.12.
Если приложение умеет вставлять не только текст
Code: Select all
if( open_clipboard() )
{
get_clipborad_info(&info_text, FORMAT_TEXT);
get_clipborad_info(&info_bitmap, FORMAT_BITMAP);
get_clipborad_info(&info_raw, FORMAT_RAW);
do_something();
buffer = read_clipboard(buffer, &size, format);
if( size != 0 )
{
do_even_more();
profit();
}
close_clipboard();
}
После обработки буфера приложение может его сохранить, удалить , изменить размер, или вернуть физические страницы ядру.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 1:49 am
by johnfound
Serge, мне твои разсуждения напоминают на Linux с котором мучаюсь напоследок. Там можно конечно делать потоки через sys_clone, но если хочется использовать xlib, то обязательно надо использовать pthreads, а память выделять через libc иначе не работает.
Дизаин системы нужно обдумывать внимательно чтобы не допускать ненужные зависимости.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 9:48 am
by Serge
johnfound
ф.68 всё же ядерные функции, а не libc. А ф.64 давно устарела.
Дизаин системы нужно обдумывать внимательно чтобы не допускать ненужные зависимости.
Этим и занимаемся. Пусть отпишутся те, кому этот буфер нужен.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 11:17 am
by SoUrcerer
Мне нужен.
Для консольных утилит, и всех остальных тоже.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 12:09 pm
by Serge
Отпишутся в смысле что они думают по поводу API. И про кодировку текста. Использовать unicode или нет ?
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 12:58 pm
by johnfound
Мне нужен для FreshLib. FreshLib работает только в UTF-8. Но мне кажется, что ядро не надо знать ничего о данных в буфере. Только надо объявить стандартные типы данных чтобы все пользовались им, а не придумывали каждый свои. И вот в этих кодов будут и TEXT_WIN1251 и TEXT_UTF8 и т.д. (кстати я назвал бы их: cltTextWin1251 и cltTextUtf8
)
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 1:05 pm
by Albom
Мне кажется, что оптимальный вариант - две подфункции.
1) Поместить данные в буфер. Через структуру.
dd type
dd size
dd address
2) Получить данные из буфера. Через ту же структуру. Буфер не очищается.
Преимущества: не нужно делать проверку перед тем, как забрать данные из буфера; скорее всего не нужно блокировать буфер (вытекает из первого); простота использования (например, установка type = 0 означает очистку буфера).
Недостатки: type для каждого типа данных должно быть уникальным; пока не могу ничего сказать о расширяемости возможностей данной функции.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 1:59 pm
by Serge
johnfound
Всё же кодировка для текста должна быть единственной. Иначе к каждой программе надо будет цеплять конвертер на все возможные варианты.
Re: Общесистемный буфер обмена
Posted: Sun Dec 09, 2012 2:43 pm
by ilya
Serge wrote:Можно и без блокировки для чтения.
Приложение создаёт буфер 68.12 и передаёт ядру указатель и размер. Ядро при необходимости увеличит размер буфера или создаст новый. Когда буфер будет ненужен приложение освободит его. Надо только учитывать что после вызова функции адрес буфера может поменяться.
Ядро создаёт буфер и передаёт во владение приложению. Когда буфер будет ненужен приложение освободит его. Такое технически возможно в даный момент?
Нельзя давать право приложению дёргать ф-цию для чтения буфера когда хочет. Только когда пользователь нажал ctrl+c в одном окне и ctrl+v вдругом. И ядро будет разбираться со всеми указателями и размерами. А если приложение хочет в другой буфер то оно может скопировать или попросить ядро перемапить для больших размеров.
Сама ф-ция чтение буфера вприципе-то не нужна за исключение когда размер скопировано превышает размер доступной памяти
Приложение посылает данные в буфер обмена если какая-то глобальная комбинация клавиш нажата. И если другая глобальная комбинация нажата в окне в фокусе то окно получает право читать из буфера для текужего ID.