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
Чёртов файрфокс упал и убил стену текста :evil:

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.