GTK°¡ Á¦°øÇÏ´Â ÇÁ·Î¼¼½º »çÀÌÀÇ Åë½ÅÇüÅ Áß Çϳª´Â selectionÀÌ´Ù. SelectionÀº »ç¿ëÀÚ°¡ ¸¶¿ì½º·Î ±Ü°Å³ª Çؼ ¼±ÅÃµÈ ÅؽºÆ®ÀÇ ÀϺΰ°Àº, µ¥ÀÌÅÍ Á¶°¢µéÀ» ÀνÄÇÑ´Ù. »ç¿ëÀÚ°¡ ¾î¶² ¼ø°£¿¡ ¼±ÅÃÇÏ°í ÀÖÀ» ¼ö ÀÖ´Â ¾îÇÃÀº Çϳª »ÓÀ̸ç, µû¶ó¼ ¾î¶² ¾îÇÿ¡ ÀÇÇØ ¼±ÅÃÀÌ ¿ä±¸µÇ¾úÀ» ¶§, ÀÌÀüÀÇ ¼ÒÀ¯ÀÚ´Â selectionÀÌ Æ÷±âµÇ¾úÀ½À» »ç¿ëÀÚ¿¡°Ô Ç¥½ÃÇØ ÁÖ¾î¾ß ÇÑ´Ù. ´Ù¸¥ ¾îÇõéÀº targetÀ̶ó ºÒ¸®´Â, ´Ù¸¥ ÇüÅÂÀÇ selectionÀ» ¿äûÇÑ´Ù. SelectionÀÇ °¹¼ö´Â Á¦ÇÑÀÌ ¾øÁö¸¸, ´ëºÎºÐÀÇ XÀ©µµ ¾îÇõéÀº primary selectionÀ̶ó°í ºÎ¸£´Â ´Ü Çϳª¸¸À» ´Ù·é´Ù.
´ëºÎºÐ °æ¿ì, GTK ¾îÇÃÀÌ selection ÀÚü¸¦ ´Ù·ê ÇÊ¿ä´Â ¾ø´Ù. Entry widget µî Ç¥ÁØÀûÀÎ widgetµéÀº »ç¿ëÀÚ°¡ ÅؽºÆ® À§·Î ¸¶¿ì½º¸¦ µå·¡±×ÇÏ´Â µîÀÇ ÇÕ´çÇÑ °æ¿ì¿¡ selectionÀ» Á¦±âÇÒ ´É·ÂÀ» ÀÌ¹Ì °¡Áö°í ÀÖÀ¸¸ç, ±×¸®°í »ç¿ëÀÚ°¡ ¸¶¿ì½º ÀÇ µÎ¹ø° ¹öÆ°À» Ŭ¸¯ÇÏ´Â °æ¿ìó·³ ´Ù¸¥ ¾îÇÃÀ̳ª widget¿¡ ÀÇÇØ ¼ÒÀ¯µÈ selection Ç׸ñµéÀ» µÇãÀ» ¼öµµ ÀÖ´Ù. ±×·¯³ª ¿ì¸®°¡ ´Ù¸¥ widgetµéÀÌ selection À» Á¦°øÇÏ´Â ´É·ÂÀ» °¡Áöµµ·Ï ÇÏ°í½ÍÀº °æ¿ìµµ ÀÖÀ» °ÍÀ̸ç, µðÆúÆ®·Î Á¦°øµÇÁö ¾Ê´Â targetÀ» µÇã°í ½ÍÀ» ¶§µµ ÀÖÀ» °ÍÀÌ´Ù.
Selection ´Ù·ç±â¸¦ ÀÌÇØÇϱâ À§ÇØ ÇÊ¿äÇÑ ±âº»ÀûÀÎ °³³äÀº atomÀ̶ó´Â
°ÍÀÌ´Ù.
AtomÀ̶õ ¾î¶² display¿¡¼, ÇÑ ¹®ÀÚ¿À» À¯ÀÏÇÏ°Ô ±¸º°ÇÒ ¼ö ÀÖ´Â ¿ÏÀüÇÑ °ÍÀÌ´Ù.
¾î¶² atomµéÀº X ¼¹ö¿¡ ÀÇÇØ ¹Ì¸® Á¤ÀǵǾî ÀÖÀ¸¸ç, ¾î¶² °æ¿ì¿£ ÀÌ·± atomµé¿¡
´ëÇÑ constantµéÀÌ gtk.h
¿¡ ÀÖÀ» ¼öµµ ÀÖ´Ù.
¿¹¸¦µé¾î »ó¼ö GDK_PRIMARY_SELECTION
Àº ¹®ÀÚ¿ "PRIMARY"¿¡ ÇØ´çµÈ´Ù.
´Ù¸¥ °æ¿ì¶ó¸é, ¿ì¸®´Â ¾î¶² ¹®ÀÚ¿
¿¡ ´ëÀÀÇÏ´Â atomÀ» ÃëÇϱâ À§ÇØ gdk_atom_interm()
À»,
±×¸®°í atomÀÇ À̸§À»
ÃëÇϱâ À§Çؼ± gdk_atom_name()
À» ÀÌ¿ëÇØ¾ß ÇÑ´Ù.
Selection°ú targetµéÀº ¸ðµÎ atom¿¡ ÀÇÇÏ¿© ½Äº°µÈ´Ù.
SelectionÀ» µÇã´Â´Ù´Â °ÍÀº ÇϳªÀÇ ºñµ¿½Ã¼ºÀÇ °úÁ¤ÀÌ´Ù. ÀÌ °úÁ¤À» ½ÃÀÛ Çϱâ À§ÇØ ÀÌ ÇÔ¼ö¸¦ ÀÌ¿ëÇÑ´Ù.
gint gtk_selection_convert (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
guint32 time)
ÀÌ°ÍÀº target
¿¡ ÀÇÇØ ¼³Á¤µÈ ÇüÅ·ΠselectionÀ» º¯È¯ÇÑ´Ù.
¸¸¾à °¡´ÉÇÏ´Ù¸é,
time ÀÎÀÚ´Â selectionÀ» °áÁ¤ÇÑ À̺¥Æ®·ÎºÎÅÍÀÇ ½Ã°£ÀÌ µÇ¾î¾ß ÇÑ´Ù. ÀÌ°ÍÀº
»ç¿ëÀÚ°¡ ¿äûÇÑ ¼ø¼´ë·Î À̺¥Æ®°¡ ¹ß»ýÇÏ´Â °ÍÀ» È®½ÇÈ÷ ÇØÁØ´Ù. ±×·¯³ª ¸¸¾à
ÀÌ°ÍÀÌ ¾²¿©Áú ¼ö ¾ø´Ù¸é(¿¹¸¦µé¾î º¯È¯ÀÌ "clicked"½Ã±×³Î¿¡ ÀÇÇØ ÀÌ·ç¾îÁ³´Ù¸é)
¿ì¸®´Â »ó¼ö GDK_CURRENT_TIME
¸¦ ÀÌ¿ëÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
Selecting owner°¡ ¾î¶² ¿ä±¸¿¡ ¹ÝÀÀÇϸé "selection_received"¶ó´Â ½Ã±×³ÎÀÌ
¿ì¸®ÀÇ ¾îÇÿ¡ º¸³»Áö°Ô µÈ´Ù. ÀÌ ½Ã±×³Î¿¡ ´ëÇÑ Çڵ鷯´Â ¾Æ·¡¿Í °°ÀÌ Á¤ÀǵÈ
GtkSelectionData
±¸Á¶Ã¼¿¡ ´ëÇÑ Æ÷ÀÎÅ͸¦ ¹Þ´Â´Ù.
struct _GtkSelectionData
{
GdkAtom selection;
GdkAtom target;
GdkAtom type;
gint format;
guchar *data;
gint length;
};
ÀÎÀÚ selection
°ú target
Àº ¿ì¸®°¡
gtk_selection_convert()
ÇÔ¼ö¿¡ ÁØ °ªµéÀÌ´Ù.
ÀÎÀÚ type
Àº selection owner¿¡ ÀÇÇØ ¸®ÅÏµÈ µ¥ÀÌÅÍ Å¸ÀÔÀ» ½Äº°ÇÏ´Â atomÀÌ´Ù.
¸î°¡Áö °¡´ÉÇÑ °ªÀ¸·Î´Â ¶óƾ ¹®ÀÚÀÇ ¹®ÀÚ¿ "STRING", atomÀÇ ½Ã¸®Áî "ATOM",
ÇϳªÀÇ Á¤¼ö "INTEGER" µîÀÌ ÀÖ´Ù. ´ëºÎºÐÀÇ targetµéÀº ¿ÀÁ÷ ÇÑ °¡Áö typeÀ»
¸®ÅÏÇÒ ¼ö ÀÖ´Ù. ÀÎÀÚ format
Àº °¢ ´ÜÀ§ÀÇ ±æÀ̸¦ ºñÆ® ´ÜÀ§·Î ÁØ °ÍÀÌ´Ù.
º¸Åë,
µ¥ÀÌÅ͸¦ ¹ÞÀ» ¶© ÀÌ°Í¿¡ ´ëÇؼ ½Å°æ¾µ ÇÊ¿ä°¡ ¾ø´Ù. ÀÎÀÚ data
´Â ¸®ÅϵÈ
µ¥ÀÌÅÍ¿¡ ´ëÇÑ Æ÷ÀÎÅ͸ç, length
´Â ÀÌ µ¥ÀÌÅÍÀÇ ±æÀ̸¦ ¹ÙÀÌÆ® ´ÜÀ§·Î ÁØ
°ÍÀÌ´Ù.
¸¸¾à length
°¡ À½¼ö¶ó¸é ¿¡·¯°¡ ¹ß»ýÇÑ °ÍÀÌ°í selectionÀº º¹±¸µÉ ¼ö ¾øÀ» °ÍÀÌ
´Ù. ÀÌ°ÍÀº ±× selectionÀ» ¼ÒÀ¯ÇÑ ¾îÇÃÀÌ ¾ø°Å³ª, ¶Ç´Â ¾îÇÃÀÌ Áö¿øÇÏÁö ¾Ê´Â
targetÀ» ¿äûÇßÀ» ¶§ ÀϾ ¼ö ÀÖ´Â ÀÏÀÌ´Ù. ½ÇÁ¦·Î ¹öÆÛ´Â length
º¸´Ù
1¹ÙÀÌÆ®
±æ°Ô µÇ´Â °ÍÀ» º¸Àå¹Þ´Â´Ù. ³²´Â ¹ÙÀÌÆ®´Â ¾ðÁ¦³ª zero°¡ µÉ °ÍÀÌ°í, µû¶ó¼
NULL·Î½á ¹®ÀÚ¿À» ³¡³»±â À§ÇØ µû·Î ¹®ÀÚ¿ÀÇ º¹»çº»À» ¸¸µé¾î µÑ ÇÊ¿ä°¡ ¾ø´Ù.
À̹ø ¿¹Á¦¿¡¼, ¿ì¸®´Â "TARGETS"¶ó´Â Ưº°ÇÑ targetÀ» º¹±¸ÇÒ °ÍÀÌ´Ù. ÀÌ°ÍÀº selectionÀÌ º¯È¯µÉ ¼ö ÀÖ´Â ¸ðµç targetÀÇ ¸®½ºÆ®ÀÌ´Ù.
#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;
/* ¹®ÀÚ¿ "TARGETS"¿¡ ÇØ´çÇÏ´Â atomÀ» ÃëÇÑ´Ù. */
if (targets_atom == GDK_NONE)
targets_atom = gdk_atom_intern ("TARGETS", FALSE);
/* ±×¸®°í primary selectionÀ¸·Î¼ "TARGETS"¶ó´Â targetÀ» ¿äûÇÑ´Ù. */
gtk_selection_convert (widget, GDK_SELECTION_PRIMARY, targets_atom,
GDK_CURRENT_TIME);
}
/* Selection owner°¡ µ¥ÀÌÅ͸¦ ¸®ÅÏÇßÀ» ¶§ ºÒ·ÁÁö´Â ½Ã±×³Î Çڵ鷯 */
void
selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
gpointer data)
{
GdkAtom *atoms;
GList *item_list;
int i;
/* **** Áß¿ä **** SelectionÀÇ º¹±¸°¡ ¼º°øÇÏ´ÂÁö üũÇÒ °Í. */
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;
}
/* ¿ì¸®°¡ ÀüÇعÞÀº atomÀ» ÇÁ¸°Æ®ÇÑ´Ù. */
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);
/* Toplevel À©µµ¸¦ ¸¸µç´Ù. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
gtk_container_border_width (GTK_CONTAINER (window), 10);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
/* »ç¿ëÀÚ°¡ targetÀ» ÃëÇÏ·Á°í Ŭ¸¯ÇÒ ¼ö ÀÖ´Â ¹öÆ°À» ¸¸µç´Ù. */
button = gtk_button_new_with_label ("Get Targets");
gtk_container_add (GTK_CONTAINER (window), button);
gtk_signal_connect (GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC (get_targets), NULL);
gtk_signal_connect (GTK_OBJECT(button), "selection_received",
GTK_SIGNAL_FUNC (selection_received), NULL);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
SelectionÀ» Á¦°øÇÏ´Â °ÍÀº Á¶±Ý ´õ º¹ÀâÇÏ´Ù. ¿ì¸®´Â ¿ì¸®ÀÇ selectionÀÌ ¿äûµÇ¾úÀ» ¶§ È£ÃâµÉ Çڵ鷯µéÀ» µî·ÏÇØ µÖ¾ß ÇÑ´Ù. ¿ì¸®°¡ ´Ù·ê °¢°¢ÀÇ selection/target ½Öµé¿¡ ´ëÇØ ÀÌ·± È£ÃâÀ» ÇÏ´Â °ÍÀÌ´Ù.
void gtk_selection_add_handler (GtkWidget *widget,
GdkAtom selection,
GdkAtom target,
GtkSelectionFunction function,
GtkRemoveFunction remove_func,
gpointer data);
widget
, selection
, target
Àº ÀÌ Çڵ鷯°¡ °ü¸®ÇÒ
¿äû(request)À» ½Äº°ÇÑ´Ù.
remove_func
ÀÎÀÚ´Â ½Ã±×³Î Çڵ鷯°¡ Á¦°ÅµÉ ¶§ NULLÀÌ ¾Æ´Ñ °ªÀÌ µÈ´Ù. ÀÌ°Ç
¿¹¸¦µé¾î, ÀÎÅÍÇÁ¸®ÅÍ ¾ð¾î°°ÀÌ µ¥ÀÌÅÍ¿¡ ´ëÇÑ reference countÀÇ Æ®·¢À» À¯ÁöÇÒ
Çʿ伺ÀÌ ÀÖ´Â °æ¿ì µî¿¡ À¯¿ëÇÏ´Ù.
ÀÌ·± ¸ð¾çÀÇ callback ÇÔ¼ö¸¦ º¸ÀÚ.
typedef void (*GtkSelectionFunction) (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data);
GtkSelectionData´Â À§¿¡¼ÀÇ °æ¿ì¿Í °°Àº °ÍÀÌÁö¸¸, À̹ø¿£ ¿ì¸®´Â Çʵ带
type
, format
, data
, ±×¸®°í length
·Î ä¿ö¾ß ÇÑ´Ù.
(Çʵå format
Àº ¿©±â¼
½ÇÁ¦·Î Áß¿äÇÏ´Ù. X ¼¹ö´Â µ¥ÀÌÅÍ°¡ byte-swapµÇ¾î¾ß ÇÏ´ÂÁöÀÇ ¿©ºÎ¸¦ ÀÌ°Í
À¸·Î½á °áÁ¤ÇÑ´Ù. º¸Åë ÀÌ°ÍÀº 8 Áï ÇϳªÀÇ ¹®ÀÚÀ̰ųª, ¶Ç´Â 32 Áï Á¤¼ö°¡
µÈ´Ù.) ÀÌ°Ç ÀÌ ÇÔ¼ö¸¦ È£ÃâÇؼ ÀÌ·ç¾îÁø´Ù.
void gtk_selection_data_set (GtkSelectionData *selection_data,
GdkAtom type,
gint format,
guchar *data,
gint length);
ÀÌ ÇÔ¼ö´Â ÀûÀýÈ÷ µ¥ÀÌÅÍÀÇ º¹»çº»À» ¸¸µéµµ·Ï ÇØÁֱ⠶§¹®¿¡ ¿ì¸®´Â µû·Î ÀÌ°Í¿¡ ½Å°æ¾µ ÇÊ¿ä°¡ ¾ø´Ù. (¿ì¸®´Â Á÷Á¢ GtkSelectionDataÀÇ ÇʵåµéÀ» ä¿ö ÁÖÁö ¾Ê¾Æµµ µÈ´Ù´Â ¸»ÀÌ´Ù.)
¿ì¸®´Â ´ÙÀ½ ÇÔ¼ö¸¦ È£ÃâÇؼ selectionÀÇ ¼ÒÀ¯±Ç(ownership)À» Á¦½ÃÇÒ ¼ö ÀÖ´Ù.
gint gtk_selection_owner_set (GtkWidget *widget,
GdkAtom selection,
guint32 time);
¸¸¾à ¶Ç´Ù¸¥ ¾îÇÃÀÌ selectionÀÇ ¼ÒÀ¯±ÇÀ» Á¦½ÃÇÑ´Ù¸é, ¿ì¸®´Â "selection_ clear_event"¸¦ ¹Þ°ÔµÉ °ÍÀÌ´Ù.
SelectionÀ» Á¦°øÇÏ´Â ¿¹Á¦·Î¼, ´ÙÀ½ ÇÁ·Î±×·¥Àº ¾î¶² Åä±Û¹öÆ°¿¡ selection ±â´ÉÀ» ÷°¡ÇÒ °ÍÀÌ´Ù. ÀÌ Åä±Û¹öÆ°ÀÌ ´·ÁÁø »óŶó¸é, ÇÁ·Î±×·¥Àº primary selectionÀ» Á¦±âÇÒ °ÍÀÌ´Ù. GTK ÀÚü¿¡ ÀÇÇØ ÁÖ¾îÁö´Â "TARGETS" °°Àº °ÍÀº Á¦ÃÄ µÎ°í, ¿©±â¼ ÁÖ¾îÁø À¯ÀÏÇÑ targetÀº "STRING" targetÀÌ´Ù. ÀÌ targetÀÌ ¿äûµÇ¸é, ½Ã°¢À» º¸¿©ÁÖ´Â ÇÑ ¹®ÀÚ¿ÀÌ ¸®ÅϵȴÙ.
#include <gtk/gtk.h>
#include <time.h>
/* »ç¿ëÀÚ°¡ selectionÀ» Åä±ÛÇÒ ¶§ È£ÃâµÇ´Â callback. */
void
selection_toggled (GtkWidget *widget, gint *have_selection)
{
if (GTK_TOGGLE_BUTTON(widget)->active)
{
*have_selection = gtk_selection_owner_set (widget,
GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
/* SelectionÀ» ¿ä±¸ÇÏ´Â µ¥ ½ÇÆÐÇϸé, out state·Î ±× ¹öÆ°À»
* ¸®ÅÏÇÑ´Ù. */
if (!*have_selection)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
}
else
{
if (*have_selection)
{
/* Selection owner¸¦ NULL·Î Çؼ selectionÀ» ºñ¿ì±â Àü¿¡,
* ¿ì¸®°¡ ÇöÀç ½ÇÁ¦ÀÇ ownerÀÎÁö üũÇÏÀÚ. */
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
GDK_CURRENT_TIME);
*have_selection = FALSE;
}
}
}
/* ´Ù¸¥ ¾îÇÃÀÌ selectionÀ» Á¦±âÇßÀ» ¶§ È£ÃâµÈ´Ù. */
gint
selection_clear (GtkWidget *widget, GdkEventSelection *event,
gint *have_selection)
{
*have_selection = FALSE;
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON(widget), FALSE);
return TRUE;
}
/* SelectionÀ¸·Î¼ ÇöÀç ½Ã°¢À» Á¦°øÇÑ´Ù. */
void
selection_handle (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data)
{
gchar *timestr;
time_t current_time;
current_time = time (NULL);
timestr = asctime (localtime(¤t_time));
/* ¿ì¸®°¡ ÇϳªÀÇ ½ºÆ®¸µÀ» ¸®ÅÏÇÒ ¶§, µû·Î NULL ¹®ÀÚ·Î ³¡À» ³»Áö
* ¾Ê¾Æµµ µÈ´Ù. ÀÌ¹Ì Ã³¸®µÇ¾î Àֱ⠶§¹®ÀÌ´Ù. */
gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
8, timestr, strlen(timestr));
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *selection_button;
static int have_selection = FALSE;
gtk_init (&argc, &argv);
/* Toplevel À©µµ¸¦ ¸¸µç´Ù. */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Event Box");
gtk_container_border_width (GTK_CONTAINER (window), 10);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
/* SelectionÀ¸·Î¼ µ¿ÀÛÇÒ Åä±Û¹öÆ°À» Çϳª ¸¸µç´Ù. */
selection_button = gtk_toggle_button_new_with_label ("Claim Selection");
gtk_container_add (GTK_CONTAINER (window), selection_button);
gtk_widget_show (selection_button);
gtk_signal_connect (GTK_OBJECT(selection_button), "toggled",
GTK_SIGNAL_FUNC (selection_toggled), &have_selection);
gtk_signal_connect (GTK_OBJECT(selection_button), "selection_clear_event",
GTK_SIGNAL_FUNC (selection_clear), &have_selection);
gtk_selection_add_handler (selection_button, GDK_SELECTION_PRIMARY,
GDK_SELECTION_TYPE_STRING,
selection_handle, NULL, NULL);
gtk_widget_show (selection_button);
gtk_widget_show (window);
gtk_main ();
return 0;
}