поиск выделения
(retrieving the selection)
поиск выделения является асинхронным
процессом, который запускается вызовом
функции:
gboolean gtk_selection_convert( gtkwidget *widget,
gdkatom selection,
gdkatom target,
guint32 time );
|
это преобразует (converts) выделение в
форму определённую target. если вообще
возможно, то аргумент time должен быть
временем события которое вызвало
выделение (selection). это помогает событиям
удостовериться в том, что пользователь
их попросил. однако, если это не доступно
(например, если преобразование было
вызвано "clicked" сигналом), то вы
можете использовать постоянный
gdk_current_time.
когда хозяин выделения отвечает на
запрос, вашему приложению посылается
сигнал "selection_received". обработчик
для этого сигнала получает указатель
на структуру gtkselectiondata, которая определена
как:
struct _gtkselectiondata
{
gdkatom selection;
gdkatom target;
gdkatom type;
gint format;
guchar *data;
gint length;
};
|
selection
и target значения которые вы дали в
вашем вызове gtk_selection_convert(). type
является атомом, который идентифицирует
тип данных, возвращенных владельцем
выбора. некоторые возможные значения
: "string" - строка из символов latin-1,
"atom" - ряд атомов, "integer" - целое
число, и т.д.. большинство targets могут
вернуть только один тип. format даёт
длину единиц (например букв) в битах.
обычно вам не нужно заботится об этом
получая данные. data - указатель на
возвращенные данные, а length -
возвращает длину данных в байтах. если
длина отрицательная, то произошла ошибка
и выделение не может быть восстановлено.
это могло случится, если у выделения
не было приложения владельца, или
запрашиваемая вами цель не поддерживается
приложением. буфер всегда гарантированно
больше length на один
байт; лишний байт всегда 0 (zero), таким
образом нет необходимости копировать
строку, только чтобы закончить её
(nul-terminate them).
в следующем примере мы восстанавливаем
специальную цель "targets", которая
является списком всех целей в которые
может быть преобразовано выделение.
#include <stdlib.h>
#include <gtk/gtk.h>
void selection_received( gtkwidget *widget,
gtkselectiondata *selection_data,
gpointer data );
/* вызываем обработчик когда пользователь нажал на кнопку "get targets" */
void get_targets( gtkwidget *widget,
gpointer data )
{
static gdkatom targets_atom = gdk_none;
gtkwidget *window = (gtkwidget *)data;
/* получаем атом соответствующий строке "targets" */
if (targets_atom == gdk_none)
targets_atom = gdk_atom_intern ("targets", false);
/* запрос цели "targets" для первичного выделения */
gtk_selection_convert (window, gdk_selection_primary, targets_atom,
gdk_current_time);
}
/* обработчик сигнала вызванный владельцем выделения возвращает данные */
void selection_received( gtkwidget *widget,
gtkselectiondata *selection_data,
gpointer data )
{
gdkatom *atoms;
glist *item_list;
int i;
/* **** важно **** проверьте успешность поиска */
if (selection_data->length < 0)
{
g_print ("selection retrieval failed\n");
return;
}
/* удостоверьтесь, что мы получили данные в ожидаемой форме */
if (selection_data->type != gdk_selection_type_atom)
{
g_print ("selection \"targets\" was not returned as atoms!\n");
return;
}
/* распечатайте атомы, которые мы получили */
atoms = (gdkatom *)selection_data->data;
item_list = null;
for (i = 0; i < selection_data->length / sizeof(gdkatom); i++)
{
char *name;
name = gdk_atom_name (atoms[i]);
if (name != null)
g_print ("%s\n",name);
else
g_print ("(bad atom)\n");
}
return;
}
int main( int argc,
char *argv[] )
{
gtkwidget *window;
gtkwidget *button;
gtk_init (&argc, &argv);
/* создаём окно верхнего уровня */
window = gtk_window_new (gtk_window_toplevel);
gtk_window_set_title (gtk_window (window), "event box");
gtk_container_set_border_width (gtk_container (window), 10);
g_signal_connect (g_object (window), "destroy",
g_callback (exit), null);
/* создаём кнопку для получения целей */
button = gtk_button_new_with_label ("get targets");
gtk_container_add (gtk_container (window), button);
g_signal_connect (g_object (button), "clicked",
g_callback (get_targets), (gpointer) window);
g_signal_connect (g_object (window), "selection_received",
g_callback (selection_received), null);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
|
|