1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 /* This file implements most of the work of the ICCCM selection protocol.
21 * The code was written after an intensive study of the equivalent part
22 * of John Ousterhout's Tk toolkit, and does many things in much the
25 * The one thing in the ICCCM that isn't fully supported here (or in Tk)
26 * is side effects targets. For these to be handled properly, MULTIPLE
27 * targets need to be done in the order specified. This cannot be
28 * guaranteed with the way we do things, since if we are doing INCR
29 * transfers, the order will depend on the timing of the requestor.
31 * By Owen Taylor <owt1@cornell.edu> 8/16/97
34 /* Terminology note: when not otherwise specified, the term "incr" below
35 * refers to the _sending_ part of the INCR protocol. The receiving
36 * portion is referred to just as "retrieval". (Terminology borrowed
37 * from Tk, because there is no good opposite to "retrieval" in English.
38 * "send" can't be made into a noun gracefully and we're already using
39 * "emission" for something else ....)
42 /* The MOTIF entry widget seems to ask for the TARGETS target, then
43 (regardless of the reply) ask for the TEXT target. It's slightly
44 possible though that it somehow thinks we are responding negatively
45 to the TARGETS request, though I don't really think so ... */
48 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
49 * file for a list of people on the GTK+ Team. See the ChangeLog
50 * files for a list of changes. These files are distributed with
51 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
55 * SECTION:gtkselection
57 * @Short_description: Functions for handling inter-process communication
59 * @See_also: #GtkWidget - Much of the operation of selections happens via
60 * signals for #GtkWidget. In particular, if you are using the functions
61 * in this section, you may need to pay attention to
62 * #GtkWidget::selection-get, #GtkWidget::selection-received and
63 * #GtkWidget::selection-clear-event signals
65 * The selection mechanism provides the basis for different types
66 * of communication between processes. In particular, drag and drop and
67 * #GtkClipboard work via selections. You will very seldom or
68 * never need to use most of the functions in this section directly;
69 * #GtkClipboard provides a nicer interface to the same functionality.
71 * Some of the datatypes defined this section are used in
72 * the #GtkClipboard and drag-and-drop API's as well. The
73 * #GtkTargetEntry structure and #GtkTargetList objects represent
74 * lists of data types that are supported when sending or
75 * receiving data. The #GtkSelectionData object is used to
76 * store a chunk of data along with the data type and other
77 * associated information.
82 #include "gtkselection.h"
83 #include "gtkselectionprivate.h"
91 #include "gtktextbufferrichtext.h"
93 #include "gdk-pixbuf/gdk-pixbuf.h"
95 #ifdef GDK_WINDOWING_X11
99 #ifdef GDK_WINDOWING_WIN32
100 #include "win32/gdkwin32.h"
103 #undef DEBUG_SELECTION
105 /* Maximum size of a sent chunk, in bytes. Also the default size of
107 #ifdef GDK_WINDOWING_X11
108 #define GTK_SELECTION_MAX_SIZE(display) \
110 XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
111 ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
112 : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
114 /* No chunks on Win32 */
115 #define GTK_SELECTION_MAX_SIZE(display) G_MAXINT
118 #define IDLE_ABORT_TIME 30
129 typedef struct _GtkSelectionInfo GtkSelectionInfo;
130 typedef struct _GtkIncrConversion GtkIncrConversion;
131 typedef struct _GtkIncrInfo GtkIncrInfo;
132 typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
134 struct _GtkSelectionInfo
137 GtkWidget *widget; /* widget that owns selection */
138 guint32 time; /* time used to acquire selection */
139 GdkDisplay *display; /* needed in gtk_selection_remove_all */
142 struct _GtkIncrConversion
144 GdkAtom target; /* Requested target */
145 GdkAtom property; /* Property to store in */
146 GtkSelectionData data; /* The data being supplied */
147 gint offset; /* Current offset in sent selection.
149 * -2 => Only the final (empty) portion
155 GdkWindow *requestor; /* Requestor window - we create a GdkWindow
156 so we can receive events */
157 GdkAtom selection; /* Selection we're sending */
159 GtkIncrConversion *conversions; /* Information about requested conversions -
160 * With MULTIPLE requests (benighted 1980's
161 * hardware idea), there can be more than
163 gint num_conversions;
164 gint num_incrs; /* number of remaining INCR style transactions */
169 struct _GtkRetrievalInfo
172 GdkAtom selection; /* Selection being retrieved. */
173 GdkAtom target; /* Form of selection that we requested */
174 guint32 idle_time; /* Number of seconds since we last heard
175 from selection owner */
176 guchar *buffer; /* Buffer in which to accumulate results */
177 gint offset; /* Current offset in buffer, -1 indicates
179 guint32 notify_time; /* Timestamp from SelectionNotify */
182 /* Local Functions */
183 static void gtk_selection_init (void);
184 static gboolean gtk_selection_incr_timeout (GtkIncrInfo *info);
185 static gboolean gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
186 static void gtk_selection_retrieval_report (GtkRetrievalInfo *info,
192 static void gtk_selection_invoke_handler (GtkWidget *widget,
193 GtkSelectionData *data,
195 static void gtk_selection_default_handler (GtkWidget *widget,
196 GtkSelectionData *data);
197 static int gtk_selection_bytes_per_item (gint format);
200 static gint initialize = TRUE;
201 static GList *current_retrievals = NULL;
202 static GList *current_incrs = NULL;
203 static GList *current_selections = NULL;
205 static GdkAtom gtk_selection_atoms[LAST_ATOM];
206 static const char gtk_selection_handler_key[] = "gtk-selection-handlers";
218 * gtk_target_list_new:
219 * @targets: (array length=ntargets): Pointer to an array of #GtkTargetEntry
220 * @ntargets: number of entries in @targets.
222 * Creates a new #GtkTargetList from an array of #GtkTargetEntry.
224 * Return value: (transfer full): the new #GtkTargetList.
227 gtk_target_list_new (const GtkTargetEntry *targets,
230 GtkTargetList *result = g_slice_new (GtkTargetList);
232 result->ref_count = 1;
235 gtk_target_list_add_table (result, targets, ntargets);
241 * gtk_target_list_ref:
242 * @list: a #GtkTargetList
244 * Increases the reference count of a #GtkTargetList by one.
246 * Return value: the passed in #GtkTargetList.
249 gtk_target_list_ref (GtkTargetList *list)
251 g_return_val_if_fail (list != NULL, NULL);
259 * gtk_target_list_unref:
260 * @list: a #GtkTargetList
262 * Decreases the reference count of a #GtkTargetList by one.
263 * If the resulting reference count is zero, frees the list.
266 gtk_target_list_unref (GtkTargetList *list)
268 g_return_if_fail (list != NULL);
269 g_return_if_fail (list->ref_count > 0);
272 if (list->ref_count == 0)
274 GList *tmp_list = list->list;
277 GtkTargetPair *pair = tmp_list->data;
278 g_slice_free (GtkTargetPair, pair);
280 tmp_list = tmp_list->next;
283 g_list_free (list->list);
284 g_slice_free (GtkTargetList, list);
289 * gtk_target_list_add:
290 * @list: a #GtkTargetList
291 * @target: the interned atom representing the target
292 * @flags: the flags for this target
293 * @info: an ID that will be passed back to the application
295 * Appends another target to a #GtkTargetList.
298 gtk_target_list_add (GtkTargetList *list,
305 g_return_if_fail (list != NULL);
307 pair = g_slice_new (GtkTargetPair);
308 pair->target = target;
312 list->list = g_list_append (list->list, pair);
315 static GdkAtom utf8_atom;
316 static GdkAtom text_atom;
317 static GdkAtom ctext_atom;
318 static GdkAtom text_plain_atom;
319 static GdkAtom text_plain_utf8_atom;
320 static GdkAtom text_plain_locale_atom;
321 static GdkAtom text_uri_list_atom;
327 const gchar *charset;
331 utf8_atom = gdk_atom_intern_static_string ("UTF8_STRING");
332 text_atom = gdk_atom_intern_static_string ("TEXT");
333 ctext_atom = gdk_atom_intern_static_string ("COMPOUND_TEXT");
334 text_plain_atom = gdk_atom_intern_static_string ("text/plain");
335 text_plain_utf8_atom = gdk_atom_intern_static_string ("text/plain;charset=utf-8");
336 g_get_charset (&charset);
337 tmp = g_strdup_printf ("text/plain;charset=%s", charset);
338 text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
341 text_uri_list_atom = gdk_atom_intern_static_string ("text/uri-list");
346 * gtk_target_list_add_text_targets:
347 * @list: a #GtkTargetList
348 * @info: an ID that will be passed back to the application
350 * Appends the text targets supported by #GtkSelection to
351 * the target list. All targets are added with the same @info.
356 gtk_target_list_add_text_targets (GtkTargetList *list,
359 g_return_if_fail (list != NULL);
363 /* Keep in sync with gtk_selection_data_targets_include_text()
365 gtk_target_list_add (list, utf8_atom, 0, info);
366 gtk_target_list_add (list, ctext_atom, 0, info);
367 gtk_target_list_add (list, text_atom, 0, info);
368 gtk_target_list_add (list, GDK_TARGET_STRING, 0, info);
369 gtk_target_list_add (list, text_plain_utf8_atom, 0, info);
370 if (!g_get_charset (NULL))
371 gtk_target_list_add (list, text_plain_locale_atom, 0, info);
372 gtk_target_list_add (list, text_plain_atom, 0, info);
376 * gtk_target_list_add_rich_text_targets:
377 * @list: a #GtkTargetList
378 * @info: an ID that will be passed back to the application
379 * @deserializable: if %TRUE, then deserializable rich text formats
380 * will be added, serializable formats otherwise.
381 * @buffer: a #GtkTextBuffer.
383 * Appends the rich text targets registered with
384 * gtk_text_buffer_register_serialize_format() or
385 * gtk_text_buffer_register_deserialize_format() to the target list. All
386 * targets are added with the same @info.
391 gtk_target_list_add_rich_text_targets (GtkTargetList *list,
393 gboolean deserializable,
394 GtkTextBuffer *buffer)
400 g_return_if_fail (list != NULL);
401 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
404 atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
406 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
408 for (i = 0; i < n_atoms; i++)
409 gtk_target_list_add (list, atoms[i], 0, info);
415 * gtk_target_list_add_image_targets:
416 * @list: a #GtkTargetList
417 * @info: an ID that will be passed back to the application
418 * @writable: whether to add only targets for which GTK+ knows
419 * how to convert a pixbuf into the format
421 * Appends the image targets supported by #GtkSelection to
422 * the target list. All targets are added with the same @info.
427 gtk_target_list_add_image_targets (GtkTargetList *list,
435 g_return_if_fail (list != NULL);
437 formats = gdk_pixbuf_get_formats ();
439 /* Make sure png comes first */
440 for (f = formats; f; f = f->next)
442 GdkPixbufFormat *fmt = f->data;
445 name = gdk_pixbuf_format_get_name (fmt);
446 if (strcmp (name, "png") == 0)
448 formats = g_slist_delete_link (formats, f);
449 formats = g_slist_prepend (formats, fmt);
459 for (f = formats; f; f = f->next)
461 GdkPixbufFormat *fmt = f->data;
463 if (writable && !gdk_pixbuf_format_is_writable (fmt))
466 mimes = gdk_pixbuf_format_get_mime_types (fmt);
467 for (m = mimes; *m; m++)
469 atom = gdk_atom_intern (*m, FALSE);
470 gtk_target_list_add (list, atom, 0, info);
475 g_slist_free (formats);
479 * gtk_target_list_add_uri_targets:
480 * @list: a #GtkTargetList
481 * @info: an ID that will be passed back to the application
483 * Appends the URI targets supported by #GtkSelection to
484 * the target list. All targets are added with the same @info.
489 gtk_target_list_add_uri_targets (GtkTargetList *list,
492 g_return_if_fail (list != NULL);
496 gtk_target_list_add (list, text_uri_list_atom, 0, info);
500 * gtk_target_list_add_table:
501 * @list: a #GtkTargetList
502 * @targets: (array length=ntargets): the table of #GtkTargetEntry
503 * @ntargets: number of targets in the table
505 * Prepends a table of #GtkTargetEntry to a target list.
508 gtk_target_list_add_table (GtkTargetList *list,
509 const GtkTargetEntry *targets,
514 for (i=ntargets-1; i >= 0; i--)
516 GtkTargetPair *pair = g_slice_new (GtkTargetPair);
517 pair->target = gdk_atom_intern (targets[i].target, FALSE);
518 pair->flags = targets[i].flags;
519 pair->info = targets[i].info;
521 list->list = g_list_prepend (list->list, pair);
526 * gtk_target_list_remove:
527 * @list: a #GtkTargetList
528 * @target: the interned atom representing the target
530 * Removes a target from a target list.
533 gtk_target_list_remove (GtkTargetList *list,
538 g_return_if_fail (list != NULL);
540 tmp_list = list->list;
543 GtkTargetPair *pair = tmp_list->data;
545 if (pair->target == target)
547 g_slice_free (GtkTargetPair, pair);
549 list->list = g_list_remove_link (list->list, tmp_list);
550 g_list_free_1 (tmp_list);
555 tmp_list = tmp_list->next;
560 * gtk_target_list_find:
561 * @list: a #GtkTargetList
562 * @target: an interned atom representing the target to search for
563 * @info: a pointer to the location to store application info for target,
566 * Looks up a given target in a #GtkTargetList.
568 * Return value: %TRUE if the target was found, otherwise %FALSE
571 gtk_target_list_find (GtkTargetList *list,
577 g_return_val_if_fail (list != NULL, FALSE);
579 tmp_list = list->list;
582 GtkTargetPair *pair = tmp_list->data;
584 if (pair->target == target)
592 tmp_list = tmp_list->next;
599 * gtk_target_table_new_from_list:
600 * @list: a #GtkTargetList
601 * @n_targets: (out): return location for the number ot targets in the table
603 * This function creates an #GtkTargetEntry array that contains the
604 * same targets as the passed %list. The returned table is newly
605 * allocated and should be freed using gtk_target_table_free() when no
608 * Return value: (array length=n_targets) (transfer full): the new table.
613 gtk_target_table_new_from_list (GtkTargetList *list,
616 GtkTargetEntry *targets;
620 g_return_val_if_fail (list != NULL, NULL);
621 g_return_val_if_fail (n_targets != NULL, NULL);
623 *n_targets = g_list_length (list->list);
624 targets = g_new0 (GtkTargetEntry, *n_targets);
626 for (i = 0, tmp_list = list->list;
628 i++, tmp_list = g_list_next (tmp_list))
630 GtkTargetPair *pair = tmp_list->data;
632 targets[i].target = gdk_atom_name (pair->target);
633 targets[i].flags = pair->flags;
634 targets[i].info = pair->info;
641 * gtk_target_table_free:
642 * @targets: (array length=n_targets): a #GtkTargetEntry array
643 * @n_targets: the number of entries in the array
645 * This function frees a target table as returned by
646 * gtk_target_table_new_from_list()
651 gtk_target_table_free (GtkTargetEntry *targets,
656 g_return_if_fail (targets == NULL || n_targets > 0);
658 for (i = 0; i < n_targets; i++)
659 g_free (targets[i].target);
665 * gtk_selection_owner_set_for_display:
666 * @display: the #Gdkdisplay where the selection is set
667 * @widget: (allow-none): new selection owner (a #GdkWidget), or %NULL.
668 * @selection: an interned atom representing the selection to claim.
669 * @time_: timestamp with which to claim the selection
671 * Claim ownership of a given selection for a particular widget, or,
672 * if @widget is %NULL, release ownership of the selection.
674 * Return value: TRUE if the operation succeeded
679 gtk_selection_owner_set_for_display (GdkDisplay *display,
685 GtkWidget *old_owner;
686 GtkSelectionInfo *selection_info = NULL;
689 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
690 g_return_val_if_fail (selection != GDK_NONE, FALSE);
691 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
692 g_return_val_if_fail (widget == NULL || gtk_widget_get_display (widget) == display, FALSE);
697 window = gtk_widget_get_window (widget);
699 tmp_list = current_selections;
702 if (((GtkSelectionInfo *)tmp_list->data)->selection == selection)
704 selection_info = tmp_list->data;
708 tmp_list = tmp_list->next;
711 if (gdk_selection_owner_set_for_display (display, window, selection, time, TRUE))
719 old_owner = selection_info->widget;
720 current_selections = g_list_remove_link (current_selections,
722 g_list_free (tmp_list);
723 g_slice_free (GtkSelectionInfo, selection_info);
728 if (selection_info == NULL)
730 selection_info = g_slice_new (GtkSelectionInfo);
731 selection_info->selection = selection;
732 selection_info->widget = widget;
733 selection_info->time = time;
734 selection_info->display = display;
735 current_selections = g_list_prepend (current_selections,
740 old_owner = selection_info->widget;
741 selection_info->widget = widget;
742 selection_info->time = time;
743 selection_info->display = display;
746 /* If another widget in the application lost the selection,
747 * send it a GDK_SELECTION_CLEAR event.
749 if (old_owner && old_owner != widget)
751 GdkEvent *event = gdk_event_new (GDK_SELECTION_CLEAR);
753 event->selection.window = g_object_ref (gtk_widget_get_window (old_owner));
754 event->selection.selection = selection;
755 event->selection.time = time;
757 gtk_widget_event (old_owner, event);
759 gdk_event_free (event);
768 * gtk_selection_owner_set:
769 * @widget: (allow-none): a #GtkWidget, or %NULL.
770 * @selection: an interned atom representing the selection to claim
771 * @time_: timestamp with which to claim the selection
773 * Claims ownership of a given selection for a particular widget,
774 * or, if @widget is %NULL, release ownership of the selection.
776 * Return value: %TRUE if the operation succeeded
779 gtk_selection_owner_set (GtkWidget *widget,
785 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
786 g_return_val_if_fail (selection != GDK_NONE, FALSE);
789 display = gtk_widget_get_display (widget);
793 g_warning ("gtk_selection_owner_set (NULL,...) is not multihead safe"));
795 display = gdk_display_get_default ();
798 return gtk_selection_owner_set_for_display (display, widget,
802 typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
804 struct _GtkSelectionTargetList {
809 static GtkTargetList *
810 gtk_selection_target_list_get (GtkWidget *widget,
813 GtkSelectionTargetList *sellist;
817 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
822 sellist = tmp_list->data;
823 if (sellist->selection == selection)
824 return sellist->list;
825 tmp_list = tmp_list->next;
828 sellist = g_slice_new (GtkSelectionTargetList);
829 sellist->selection = selection;
830 sellist->list = gtk_target_list_new (NULL, 0);
832 lists = g_list_prepend (lists, sellist);
833 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
835 return sellist->list;
839 gtk_selection_target_list_remove (GtkWidget *widget)
841 GtkSelectionTargetList *sellist;
845 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
850 sellist = tmp_list->data;
852 gtk_target_list_unref (sellist->list);
854 g_slice_free (GtkSelectionTargetList, sellist);
855 tmp_list = tmp_list->next;
859 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), NULL);
863 * gtk_selection_clear_targets:
864 * @widget: a #GtkWidget
865 * @selection: an atom representing a selection
867 * Remove all targets registered for the given selection for the
871 gtk_selection_clear_targets (GtkWidget *widget,
874 GtkSelectionTargetList *sellist;
878 g_return_if_fail (GTK_IS_WIDGET (widget));
879 g_return_if_fail (selection != GDK_NONE);
881 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
886 sellist = tmp_list->data;
887 if (sellist->selection == selection)
889 lists = g_list_delete_link (lists, tmp_list);
890 gtk_target_list_unref (sellist->list);
891 g_slice_free (GtkSelectionTargetList, sellist);
896 tmp_list = tmp_list->next;
899 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
903 * gtk_selection_add_target:
904 * @widget: a #GtkTarget
905 * @selection: the selection
906 * @target: target to add.
907 * @info: A unsigned integer which will be passed back to the application.
909 * Appends a specified target to the list of supported targets for a
910 * given widget and selection.
913 gtk_selection_add_target (GtkWidget *widget,
920 g_return_if_fail (GTK_IS_WIDGET (widget));
921 g_return_if_fail (selection != GDK_NONE);
923 list = gtk_selection_target_list_get (widget, selection);
924 gtk_target_list_add (list, target, 0, info);
925 #ifdef GDK_WINDOWING_WIN32
926 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, 1, &target);
931 * gtk_selection_add_targets:
932 * @widget: a #GtkWidget
933 * @selection: the selection
934 * @targets: (array length=ntargets): a table of targets to add
935 * @ntargets: number of entries in @targets
937 * Prepends a table of targets to the list of supported targets
938 * for a given widget and selection.
941 gtk_selection_add_targets (GtkWidget *widget,
943 const GtkTargetEntry *targets,
948 g_return_if_fail (GTK_IS_WIDGET (widget));
949 g_return_if_fail (selection != GDK_NONE);
950 g_return_if_fail (targets != NULL);
952 list = gtk_selection_target_list_get (widget, selection);
953 gtk_target_list_add_table (list, targets, ntargets);
955 #ifdef GDK_WINDOWING_WIN32
958 GdkAtom *atoms = g_new (GdkAtom, ntargets);
960 for (i = 0; i < ntargets; ++i)
961 atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
962 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, ntargets, atoms);
970 * gtk_selection_remove_all:
971 * @widget: a #GtkWidget
973 * Removes all handlers and unsets ownership of all
974 * selections for a widget. Called when widget is being
975 * destroyed. This function will not generally be
976 * called by applications.
979 gtk_selection_remove_all (GtkWidget *widget)
983 GtkSelectionInfo *selection_info;
985 g_return_if_fail (GTK_IS_WIDGET (widget));
987 /* Remove pending requests/incrs for this widget */
989 tmp_list = current_retrievals;
992 next = tmp_list->next;
993 if (((GtkRetrievalInfo *)tmp_list->data)->widget == widget)
995 current_retrievals = g_list_remove_link (current_retrievals,
997 /* structure will be freed in timeout */
998 g_list_free (tmp_list);
1003 /* Disclaim ownership of any selections */
1005 tmp_list = current_selections;
1008 next = tmp_list->next;
1009 selection_info = (GtkSelectionInfo *)tmp_list->data;
1011 if (selection_info->widget == widget)
1013 gdk_selection_owner_set_for_display (selection_info->display,
1015 selection_info->selection,
1016 GDK_CURRENT_TIME, FALSE);
1017 current_selections = g_list_remove_link (current_selections,
1019 g_list_free (tmp_list);
1020 g_slice_free (GtkSelectionInfo, selection_info);
1026 /* Remove all selection lists */
1027 gtk_selection_target_list_remove (widget);
1032 * gtk_selection_convert:
1033 * @widget: The widget which acts as requestor
1034 * @selection: Which selection to get
1035 * @target: Form of information desired (e.g., STRING)
1036 * @time_: Time of request (usually of triggering event)
1037 In emergency, you could use #GDK_CURRENT_TIME
1039 * Requests the contents of a selection. When received,
1040 * a "selection-received" signal will be generated.
1042 * Return value: %TRUE if requested succeeded. %FALSE if we could not process
1043 * request. (e.g., there was already a request in process for
1047 gtk_selection_convert (GtkWidget *widget,
1052 GtkRetrievalInfo *info;
1054 GdkWindow *owner_window;
1055 GdkDisplay *display;
1057 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1058 g_return_val_if_fail (selection != GDK_NONE, FALSE);
1061 gtk_selection_init ();
1063 if (!gtk_widget_get_realized (widget))
1064 gtk_widget_realize (widget);
1066 /* Check to see if there are already any retrievals in progress for
1067 this widget. If we changed GDK to use the selection for the
1068 window property in which to store the retrieved information, then
1069 we could support multiple retrievals for different selections.
1070 This might be useful for DND. */
1072 tmp_list = current_retrievals;
1075 info = (GtkRetrievalInfo *)tmp_list->data;
1076 if (info->widget == widget)
1078 tmp_list = tmp_list->next;
1081 info = g_slice_new (GtkRetrievalInfo);
1083 info->widget = widget;
1084 info->selection = selection;
1085 info->target = target;
1086 info->idle_time = 0;
1087 info->buffer = NULL;
1090 /* Check if this process has current owner. If so, call handler
1091 procedure directly to avoid deadlocks with INCR. */
1093 display = gtk_widget_get_display (widget);
1094 owner_window = gdk_selection_owner_get_for_display (display, selection);
1096 if (owner_window != NULL)
1098 GtkWidget *owner_widget;
1099 gpointer owner_widget_ptr;
1100 GtkSelectionData selection_data = {0};
1102 selection_data.selection = selection;
1103 selection_data.target = target;
1104 selection_data.length = -1;
1105 selection_data.display = display;
1107 gdk_window_get_user_data (owner_window, &owner_widget_ptr);
1108 owner_widget = owner_widget_ptr;
1110 if (owner_widget != NULL)
1112 gtk_selection_invoke_handler (owner_widget,
1116 gtk_selection_retrieval_report (info,
1117 selection_data.type,
1118 selection_data.format,
1119 selection_data.data,
1120 selection_data.length,
1123 g_free (selection_data.data);
1124 selection_data.data = NULL;
1125 selection_data.length = -1;
1127 g_slice_free (GtkRetrievalInfo, info);
1132 /* Otherwise, we need to go through X */
1134 current_retrievals = g_list_append (current_retrievals, info);
1135 gdk_selection_convert (gtk_widget_get_window (widget), selection, target, time_);
1136 gdk_threads_add_timeout (1000,
1137 (GSourceFunc) gtk_selection_retrieval_timeout, info);
1143 * gtk_selection_data_get_selection:
1144 * @selection_data: a pointer to a #GtkSelectionData structure.
1146 * Retrieves the selection #GdkAtom of the selection data.
1148 * Returns: (transfer none): the selection #GdkAtom of the selection data.
1153 gtk_selection_data_get_selection (const GtkSelectionData *selection_data)
1155 g_return_val_if_fail (selection_data != NULL, 0);
1157 return selection_data->selection;
1161 * gtk_selection_data_get_target:
1162 * @selection_data: a pointer to a #GtkSelectionData structure.
1164 * Retrieves the target of the selection.
1166 * Returns: (transfer none): the target of the selection.
1171 gtk_selection_data_get_target (const GtkSelectionData *selection_data)
1173 g_return_val_if_fail (selection_data != NULL, 0);
1175 return selection_data->target;
1179 * gtk_selection_data_get_data_type:
1180 * @selection_data: a pointer to a #GtkSelectionData structure.
1182 * Retrieves the data type of the selection.
1184 * Returns: (transfer none): the data type of the selection.
1189 gtk_selection_data_get_data_type (const GtkSelectionData *selection_data)
1191 g_return_val_if_fail (selection_data != NULL, 0);
1193 return selection_data->type;
1197 * gtk_selection_data_get_format:
1198 * @selection_data: a pointer to a #GtkSelectionData structure.
1200 * Retrieves the format of the selection.
1202 * Returns: the format of the selection.
1207 gtk_selection_data_get_format (const GtkSelectionData *selection_data)
1209 g_return_val_if_fail (selection_data != NULL, 0);
1211 return selection_data->format;
1215 * gtk_selection_data_get_data: (skip)
1216 * @selection_data: a pointer to a #GtkSelectionData structure.
1218 * Retrieves the raw data of the selection.
1220 * Returns: the raw data of the selection.
1225 gtk_selection_data_get_data (const GtkSelectionData *selection_data)
1227 g_return_val_if_fail (selection_data != NULL, NULL);
1229 return selection_data->data;
1233 * gtk_selection_data_get_length:
1234 * @selection_data: a pointer to a #GtkSelectionData structure.
1236 * Retrieves the length of the raw data of the selection.
1238 * Returns: the length of the data of the selection.
1243 gtk_selection_data_get_length (const GtkSelectionData *selection_data)
1245 g_return_val_if_fail (selection_data != NULL, -1);
1247 return selection_data->length;
1251 * gtk_selection_data_get_data_with_length:
1252 * @selection_data: a pointer to a #GtkSelectionData structure
1253 * @length: (out): return location for length of the data segment
1255 * Retrieves the raw data of the selection along with its length.
1257 * Returns: (array length=length): the raw data of the selection
1259 * Rename to: gtk_selection_data_get_data
1263 gtk_selection_data_get_data_with_length (const GtkSelectionData *selection_data,
1266 g_return_val_if_fail (selection_data != NULL, NULL);
1268 *length = selection_data->length;
1270 return selection_data->data;
1274 * gtk_selection_data_get_display:
1275 * @selection_data: a pointer to a #GtkSelectionData structure.
1277 * Retrieves the display of the selection.
1279 * Returns: (transfer none): the display of the selection.
1284 gtk_selection_data_get_display (const GtkSelectionData *selection_data)
1286 g_return_val_if_fail (selection_data != NULL, NULL);
1288 return selection_data->display;
1292 * gtk_selection_data_set:
1293 * @selection_data: a pointer to a #GtkSelectionData structure.
1294 * @type: the type of selection data
1295 * @format: format (number of bits in a unit)
1296 * @data: (array length=length): pointer to the data (will be copied)
1297 * @length: length of the data
1299 * Stores new data into a #GtkSelectionData object. Should
1300 * <emphasis>only</emphasis> be called from a selection handler callback.
1301 * Zero-terminates the stored data.
1304 gtk_selection_data_set (GtkSelectionData *selection_data,
1310 g_return_if_fail (selection_data != NULL);
1312 g_free (selection_data->data);
1314 selection_data->type = type;
1315 selection_data->format = format;
1319 selection_data->data = g_new (guchar, length+1);
1320 memcpy (selection_data->data, data, length);
1321 selection_data->data[length] = 0;
1325 g_return_if_fail (length <= 0);
1328 selection_data->data = NULL;
1330 selection_data->data = (guchar *) g_strdup ("");
1333 selection_data->length = length;
1337 selection_set_string (GtkSelectionData *selection_data,
1341 gchar *tmp = g_strndup (str, len);
1342 gchar *latin1 = gdk_utf8_to_string_target (tmp);
1347 gtk_selection_data_set (selection_data,
1348 GDK_SELECTION_TYPE_STRING,
1349 8, (guchar *) latin1, strlen (latin1));
1359 selection_set_compound_text (GtkSelectionData *selection_data,
1368 gboolean result = FALSE;
1370 #ifdef GDK_WINDOWING_X11
1371 if (GDK_IS_X11_DISPLAY (selection_data->display))
1373 tmp = g_strndup (str, len);
1374 if (gdk_x11_display_utf8_to_compound_text (selection_data->display, tmp,
1375 &encoding, &format, &text, &new_length))
1377 gtk_selection_data_set (selection_data, encoding, format, text, new_length);
1378 gdk_x11_free_compound_text (text);
1389 /* Normalize \r and \n into \r\n
1392 normalize_to_crlf (const gchar *str,
1395 GString *result = g_string_sized_new (len);
1396 const gchar *p = str;
1397 const gchar *end = str + len;
1402 g_string_append_c (result, '\r');
1406 g_string_append_c (result, *p);
1408 if (p == end || *p != '\n')
1409 g_string_append_c (result, '\n');
1414 g_string_append_c (result, *p);
1418 return g_string_free (result, FALSE);
1421 /* Normalize \r and \r\n into \n
1424 normalize_to_lf (gchar *str,
1427 GString *result = g_string_sized_new (len);
1428 const gchar *p = str;
1436 g_string_append_c (result, '\n');
1442 g_string_append_c (result, *p);
1446 return g_string_free (result, FALSE);
1450 selection_set_text_plain (GtkSelectionData *selection_data,
1454 const gchar *charset = NULL;
1456 GError *error = NULL;
1458 result = normalize_to_crlf (str, len);
1459 if (selection_data->target == text_plain_atom)
1461 else if (selection_data->target == text_plain_locale_atom)
1462 g_get_charset (&charset);
1466 gchar *tmp = result;
1467 result = g_convert_with_fallback (tmp, -1,
1469 NULL, NULL, NULL, &error);
1475 g_warning ("Error converting from %s to %s: %s",
1476 "UTF-8", charset, error->message);
1477 g_error_free (error);
1482 gtk_selection_data_set (selection_data,
1483 selection_data->target,
1484 8, (guchar *) result, strlen (result));
1491 selection_get_text_plain (const GtkSelectionData *selection_data)
1493 const gchar *charset = NULL;
1494 gchar *str, *result;
1496 GError *error = NULL;
1498 str = g_strdup ((const gchar *) selection_data->data);
1499 len = selection_data->length;
1501 if (selection_data->type == text_plain_atom)
1502 charset = "ISO-8859-1";
1503 else if (selection_data->type == text_plain_locale_atom)
1504 g_get_charset (&charset);
1509 str = g_convert_with_fallback (tmp, len,
1511 NULL, NULL, &len, &error);
1516 g_warning ("Error converting from %s to %s: %s",
1517 charset, "UTF-8", error->message);
1518 g_error_free (error);
1523 else if (!g_utf8_validate (str, -1, NULL))
1525 g_warning ("Error converting from %s to %s: %s",
1526 "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8");
1532 result = normalize_to_lf (str, len);
1535 return (guchar *) result;
1539 * gtk_selection_data_set_text:
1540 * @selection_data: a #GtkSelectionData
1541 * @str: a UTF-8 string
1542 * @len: the length of @str, or -1 if @str is nul-terminated.
1544 * Sets the contents of the selection from a UTF-8 encoded string.
1545 * The string is converted to the form determined by
1546 * @selection_data->target.
1548 * Return value: %TRUE if the selection was successfully set,
1552 gtk_selection_data_set_text (GtkSelectionData *selection_data,
1556 g_return_val_if_fail (selection_data != NULL, FALSE);
1563 if (selection_data->target == utf8_atom)
1565 gtk_selection_data_set (selection_data,
1567 8, (guchar *)str, len);
1570 else if (selection_data->target == GDK_TARGET_STRING)
1572 return selection_set_string (selection_data, str, len);
1574 else if (selection_data->target == ctext_atom ||
1575 selection_data->target == text_atom)
1577 if (selection_set_compound_text (selection_data, str, len))
1579 else if (selection_data->target == text_atom)
1580 return selection_set_string (selection_data, str, len);
1582 else if (selection_data->target == text_plain_atom ||
1583 selection_data->target == text_plain_utf8_atom ||
1584 selection_data->target == text_plain_locale_atom)
1586 return selection_set_text_plain (selection_data, str, len);
1593 * gtk_selection_data_get_text:
1594 * @selection_data: a #GtkSelectionData
1596 * Gets the contents of the selection data as a UTF-8 string.
1598 * Return value: (type utf8): if the selection data contained a
1599 * recognized text type and it could be converted to UTF-8, a newly
1600 * allocated string containing the converted text, otherwise %NULL.
1601 * If the result is non-%NULL it must be freed with g_free().
1604 gtk_selection_data_get_text (const GtkSelectionData *selection_data)
1606 guchar *result = NULL;
1608 g_return_val_if_fail (selection_data != NULL, NULL);
1612 if (selection_data->length >= 0 &&
1613 (selection_data->type == GDK_TARGET_STRING ||
1614 selection_data->type == ctext_atom ||
1615 selection_data->type == utf8_atom))
1619 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1620 selection_data->type,
1621 selection_data->format,
1622 selection_data->data,
1623 selection_data->length,
1626 result = (guchar *) list[0];
1628 for (i = 1; i < count; i++)
1632 else if (selection_data->length >= 0 &&
1633 (selection_data->type == text_plain_atom ||
1634 selection_data->type == text_plain_utf8_atom ||
1635 selection_data->type == text_plain_locale_atom))
1637 result = selection_get_text_plain (selection_data);
1644 * gtk_selection_data_set_pixbuf:
1645 * @selection_data: a #GtkSelectionData
1646 * @pixbuf: a #GdkPixbuf
1648 * Sets the contents of the selection from a #GdkPixbuf
1649 * The pixbuf is converted to the form determined by
1650 * @selection_data->target.
1652 * Return value: %TRUE if the selection was successfully set,
1658 gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
1661 GSList *formats, *f;
1668 g_return_val_if_fail (selection_data != NULL, FALSE);
1669 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
1671 formats = gdk_pixbuf_get_formats ();
1673 for (f = formats; f; f = f->next)
1675 GdkPixbufFormat *fmt = f->data;
1677 mimes = gdk_pixbuf_format_get_mime_types (fmt);
1678 for (m = mimes; *m; m++)
1680 atom = gdk_atom_intern (*m, FALSE);
1681 if (selection_data->target == atom)
1684 type = gdk_pixbuf_format_get_name (fmt);
1685 result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len,
1687 ((strcmp (type, "png") == 0) ?
1688 "compression" : NULL), "2",
1691 gtk_selection_data_set (selection_data,
1692 atom, 8, (guchar *)str, len);
1696 g_slist_free (formats);
1705 g_slist_free (formats);
1711 * gtk_selection_data_get_pixbuf:
1712 * @selection_data: a #GtkSelectionData
1714 * Gets the contents of the selection data as a #GdkPixbuf.
1716 * Return value: (transfer full): if the selection data contained a recognized
1717 * image type and it could be converted to a #GdkPixbuf, a
1718 * newly allocated pixbuf is returned, otherwise %NULL.
1719 * If the result is non-%NULL it must be freed with g_object_unref().
1724 gtk_selection_data_get_pixbuf (const GtkSelectionData *selection_data)
1726 GdkPixbufLoader *loader;
1727 GdkPixbuf *result = NULL;
1729 g_return_val_if_fail (selection_data != NULL, NULL);
1731 if (selection_data->length > 0)
1733 loader = gdk_pixbuf_loader_new ();
1735 gdk_pixbuf_loader_write (loader,
1736 selection_data->data,
1737 selection_data->length,
1739 gdk_pixbuf_loader_close (loader, NULL);
1740 result = gdk_pixbuf_loader_get_pixbuf (loader);
1743 g_object_ref (result);
1745 g_object_unref (loader);
1752 * gtk_selection_data_set_uris:
1753 * @selection_data: a #GtkSelectionData
1754 * @uris: (array zero-terminated=1): a %NULL-terminated array of
1755 * strings holding URIs
1757 * Sets the contents of the selection from a list of URIs.
1758 * The string is converted to the form determined by
1759 * @selection_data->target.
1761 * Return value: %TRUE if the selection was successfully set,
1767 gtk_selection_data_set_uris (GtkSelectionData *selection_data,
1770 g_return_val_if_fail (selection_data != NULL, FALSE);
1771 g_return_val_if_fail (uris != NULL, FALSE);
1775 if (selection_data->target == text_uri_list_atom)
1782 list = g_string_new (NULL);
1783 for (i = 0; uris[i]; i++)
1785 g_string_append (list, uris[i]);
1786 g_string_append (list, "\r\n");
1789 result = g_convert (list->str, list->len,
1791 NULL, &length, NULL);
1792 g_string_free (list, TRUE);
1796 gtk_selection_data_set (selection_data,
1798 8, (guchar *)result, length);
1810 * gtk_selection_data_get_uris:
1811 * @selection_data: a #GtkSelectionData
1813 * Gets the contents of the selection data as array of URIs.
1815 * Return value: (array zero-terminated=1) (element-type utf8) (transfer full): if
1816 * the selection data contains a list of
1817 * URIs, a newly allocated %NULL-terminated string array
1818 * containing the URIs, otherwise %NULL. If the result is
1819 * non-%NULL it must be freed with g_strfreev().
1824 gtk_selection_data_get_uris (const GtkSelectionData *selection_data)
1826 gchar **result = NULL;
1828 g_return_val_if_fail (selection_data != NULL, NULL);
1832 if (selection_data->length >= 0 &&
1833 selection_data->type == text_uri_list_atom)
1836 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1838 selection_data->format,
1839 selection_data->data,
1840 selection_data->length,
1843 result = g_uri_list_extract_uris (list[0]);
1853 * gtk_selection_data_get_targets:
1854 * @selection_data: a #GtkSelectionData object
1855 * @targets: (out) (array length=n_atoms) (transfer container):
1856 * location to store an array of targets. The result stored
1857 * here must be freed with g_free().
1858 * @n_atoms: location to store number of items in @targets.
1860 * Gets the contents of @selection_data as an array of targets.
1861 * This can be used to interpret the results of getting
1862 * the standard TARGETS target that is always supplied for
1865 * Return value: %TRUE if @selection_data contains a valid
1866 * array of targets, otherwise %FALSE.
1869 gtk_selection_data_get_targets (const GtkSelectionData *selection_data,
1873 g_return_val_if_fail (selection_data != NULL, FALSE);
1875 if (selection_data->length >= 0 &&
1876 selection_data->format == 32 &&
1877 selection_data->type == GDK_SELECTION_TYPE_ATOM)
1880 *targets = g_memdup (selection_data->data, selection_data->length);
1882 *n_atoms = selection_data->length / sizeof (GdkAtom);
1898 * gtk_targets_include_text:
1899 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1900 * @n_targets: the length of @targets
1902 * Determines if any of the targets in @targets can be used to
1905 * Return value: %TRUE if @targets include a suitable target for text,
1911 gtk_targets_include_text (GdkAtom *targets,
1915 gboolean result = FALSE;
1917 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1919 /* Keep in sync with gtk_target_list_add_text_targets()
1924 for (i = 0; i < n_targets; i++)
1926 if (targets[i] == utf8_atom ||
1927 targets[i] == text_atom ||
1928 targets[i] == GDK_TARGET_STRING ||
1929 targets[i] == ctext_atom ||
1930 targets[i] == text_plain_atom ||
1931 targets[i] == text_plain_utf8_atom ||
1932 targets[i] == text_plain_locale_atom)
1943 * gtk_targets_include_rich_text:
1944 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1945 * @n_targets: the length of @targets
1946 * @buffer: a #GtkTextBuffer
1948 * Determines if any of the targets in @targets can be used to
1949 * provide rich text.
1951 * Return value: %TRUE if @targets include a suitable target for rich text,
1957 gtk_targets_include_rich_text (GdkAtom *targets,
1959 GtkTextBuffer *buffer)
1961 GdkAtom *rich_targets;
1962 gint n_rich_targets;
1964 gboolean result = FALSE;
1966 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1967 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1971 rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
1974 for (i = 0; i < n_targets; i++)
1976 for (j = 0; j < n_rich_targets; j++)
1978 if (targets[i] == rich_targets[j])
1987 g_free (rich_targets);
1993 * gtk_selection_data_targets_include_text:
1994 * @selection_data: a #GtkSelectionData object
1996 * Given a #GtkSelectionData object holding a list of targets,
1997 * determines if any of the targets in @targets can be used to
2000 * Return value: %TRUE if @selection_data holds a list of targets,
2001 * and a suitable target for text is included, otherwise %FALSE.
2004 gtk_selection_data_targets_include_text (const GtkSelectionData *selection_data)
2008 gboolean result = FALSE;
2010 g_return_val_if_fail (selection_data != NULL, FALSE);
2014 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2016 result = gtk_targets_include_text (targets, n_targets);
2024 * gtk_selection_data_targets_include_rich_text:
2025 * @selection_data: a #GtkSelectionData object
2026 * @buffer: a #GtkTextBuffer
2028 * Given a #GtkSelectionData object holding a list of targets,
2029 * determines if any of the targets in @targets can be used to
2030 * provide rich text.
2032 * Return value: %TRUE if @selection_data holds a list of targets,
2033 * and a suitable target for rich text is included,
2039 gtk_selection_data_targets_include_rich_text (const GtkSelectionData *selection_data,
2040 GtkTextBuffer *buffer)
2044 gboolean result = FALSE;
2046 g_return_val_if_fail (selection_data != NULL, FALSE);
2047 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2051 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2053 result = gtk_targets_include_rich_text (targets, n_targets, buffer);
2061 * gtk_targets_include_image:
2062 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2063 * @n_targets: the length of @targets
2064 * @writable: whether to accept only targets for which GTK+ knows
2065 * how to convert a pixbuf into the format
2067 * Determines if any of the targets in @targets can be used to
2068 * provide a #GdkPixbuf.
2070 * Return value: %TRUE if @targets include a suitable target for images,
2076 gtk_targets_include_image (GdkAtom *targets,
2080 GtkTargetList *list;
2083 gboolean result = FALSE;
2085 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2087 list = gtk_target_list_new (NULL, 0);
2088 gtk_target_list_add_image_targets (list, 0, writable);
2089 for (i = 0; i < n_targets && !result; i++)
2091 for (l = list->list; l; l = l->next)
2093 GtkTargetPair *pair = (GtkTargetPair *)l->data;
2094 if (pair->target == targets[i])
2101 gtk_target_list_unref (list);
2107 * gtk_selection_data_targets_include_image:
2108 * @selection_data: a #GtkSelectionData object
2109 * @writable: whether to accept only targets for which GTK+ knows
2110 * how to convert a pixbuf into the format
2112 * Given a #GtkSelectionData object holding a list of targets,
2113 * determines if any of the targets in @targets can be used to
2114 * provide a #GdkPixbuf.
2116 * Return value: %TRUE if @selection_data holds a list of targets,
2117 * and a suitable target for images is included, otherwise %FALSE.
2122 gtk_selection_data_targets_include_image (const GtkSelectionData *selection_data,
2127 gboolean result = FALSE;
2129 g_return_val_if_fail (selection_data != NULL, FALSE);
2133 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2135 result = gtk_targets_include_image (targets, n_targets, writable);
2143 * gtk_targets_include_uri:
2144 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2145 * @n_targets: the length of @targets
2147 * Determines if any of the targets in @targets can be used to
2148 * provide an uri list.
2150 * Return value: %TRUE if @targets include a suitable target for uri lists,
2156 gtk_targets_include_uri (GdkAtom *targets,
2160 gboolean result = FALSE;
2162 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2164 /* Keep in sync with gtk_target_list_add_uri_targets()
2169 for (i = 0; i < n_targets; i++)
2171 if (targets[i] == text_uri_list_atom)
2182 * gtk_selection_data_targets_include_uri:
2183 * @selection_data: a #GtkSelectionData object
2185 * Given a #GtkSelectionData object holding a list of targets,
2186 * determines if any of the targets in @targets can be used to
2187 * provide a list or URIs.
2189 * Return value: %TRUE if @selection_data holds a list of targets,
2190 * and a suitable target for URI lists is included, otherwise %FALSE.
2195 gtk_selection_data_targets_include_uri (const GtkSelectionData *selection_data)
2199 gboolean result = FALSE;
2201 g_return_val_if_fail (selection_data != NULL, FALSE);
2205 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2207 result = gtk_targets_include_uri (targets, n_targets);
2215 /*************************************************************
2216 * gtk_selection_init:
2217 * Initialize local variables
2221 *************************************************************/
2224 gtk_selection_init (void)
2226 gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
2227 gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
2228 gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
2229 gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
2230 gtk_selection_atoms[SAVE_TARGETS] = gdk_atom_intern_static_string ("SAVE_TARGETS");
2236 * _gtk_selection_clear:
2237 * @widget: a #GtkWidget
2240 * The default handler for the #GtkWidget::selection-clear-event
2243 * Return value: %TRUE if the event was handled, otherwise false
2246 _gtk_selection_clear (GtkWidget *widget,
2247 GdkEventSelection *event)
2249 /* Note that we filter clear events in gdkselection-x11.c, so
2250 * that we only will get here if the clear event actually
2251 * represents a change that we didn't do ourself.
2254 GtkSelectionInfo *selection_info = NULL;
2256 tmp_list = current_selections;
2259 selection_info = (GtkSelectionInfo *)tmp_list->data;
2261 if ((selection_info->selection == event->selection) &&
2262 (selection_info->widget == widget))
2265 tmp_list = tmp_list->next;
2270 current_selections = g_list_remove_link (current_selections, tmp_list);
2271 g_list_free (tmp_list);
2272 g_slice_free (GtkSelectionInfo, selection_info);
2279 /*************************************************************
2280 * _gtk_selection_request:
2281 * Handler for "selection_request_event"
2286 *************************************************************/
2289 _gtk_selection_request (GtkWidget *widget,
2290 GdkEventSelection *event)
2292 GdkDisplay *display = gtk_widget_get_display (widget);
2296 gulong selection_max_size;
2299 gtk_selection_init ();
2301 selection_max_size = GTK_SELECTION_MAX_SIZE (display);
2303 /* Check if we own selection */
2305 tmp_list = current_selections;
2308 GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
2310 if ((selection_info->selection == event->selection) &&
2311 (selection_info->widget == widget))
2314 tmp_list = tmp_list->next;
2317 if (tmp_list == NULL)
2320 info = g_slice_new (GtkIncrInfo);
2322 g_object_ref (widget);
2324 info->selection = event->selection;
2325 info->num_incrs = 0;
2326 info->requestor = g_object_ref (event->requestor);
2328 /* Determine conversions we need to perform */
2329 if (event->target == gtk_selection_atoms[MULTIPLE])
2338 gdk_error_trap_push ();
2339 if (!gdk_property_get (info->requestor, event->property, GDK_NONE, /* AnyPropertyType */
2340 0, selection_max_size, FALSE,
2341 &type, &format, &length, &mult_atoms))
2343 gdk_selection_send_notify_for_display (display,
2349 g_free (mult_atoms);
2350 g_slice_free (GtkIncrInfo, info);
2351 gdk_error_trap_pop_ignored ();
2354 gdk_error_trap_pop_ignored ();
2356 /* This is annoying; the ICCCM doesn't specify the property type
2357 * used for the property contents, so the autoconversion for
2358 * ATOM / ATOM_PAIR in GDK doesn't work properly.
2360 #ifdef GDK_WINDOWING_X11
2361 if (type != GDK_SELECTION_TYPE_ATOM &&
2362 type != gdk_atom_intern_static_string ("ATOM_PAIR"))
2364 info->num_conversions = length / (2*sizeof (glong));
2365 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2367 for (i=0; i<info->num_conversions; i++)
2369 info->conversions[i].target = gdk_x11_xatom_to_atom_for_display (display,
2370 ((glong *)mult_atoms)[2*i]);
2371 info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
2372 ((glong *)mult_atoms)[2*i + 1]);
2375 g_free (mult_atoms);
2380 info->num_conversions = length / (2*sizeof (GdkAtom));
2381 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2383 for (i=0; i<info->num_conversions; i++)
2385 info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
2386 info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
2389 g_free (mult_atoms);
2392 else /* only a single conversion */
2394 info->conversions = g_new (GtkIncrConversion, 1);
2395 info->num_conversions = 1;
2396 info->conversions[0].target = event->target;
2397 info->conversions[0].property = event->property;
2400 /* Loop through conversions and determine which of these are big
2401 enough to require doing them via INCR */
2402 for (i=0; i<info->num_conversions; i++)
2404 GtkSelectionData data;
2407 data.selection = event->selection;
2408 data.target = info->conversions[i].target;
2411 data.display = gtk_widget_get_display (widget);
2413 #ifdef DEBUG_SELECTION
2414 g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
2416 info->conversions[i].target,
2417 gdk_atom_name (info->conversions[i].target),
2418 event->requestor, info->conversions[i].property);
2421 gtk_selection_invoke_handler (widget, &data, event->time);
2422 if (data.length < 0)
2424 info->conversions[i].property = GDK_NONE;
2428 g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE);
2430 items = data.length / gtk_selection_bytes_per_item (data.format);
2432 if (data.length > selection_max_size)
2434 /* Sending via INCR */
2435 #ifdef DEBUG_SELECTION
2436 g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n",
2437 data.length, selection_max_size);
2440 info->conversions[i].offset = 0;
2441 info->conversions[i].data = data;
2444 gdk_property_change (info->requestor,
2445 info->conversions[i].property,
2446 gtk_selection_atoms[INCR],
2448 GDK_PROP_MODE_REPLACE,
2449 (guchar *)&items, 1);
2453 info->conversions[i].offset = -1;
2455 gdk_property_change (info->requestor,
2456 info->conversions[i].property,
2459 GDK_PROP_MODE_REPLACE,
2466 /* If we have some INCR's, we need to send the rest of the data in
2469 if (info->num_incrs > 0)
2471 /* FIXME: this could be dangerous if window doesn't still
2474 #ifdef DEBUG_SELECTION
2475 g_message ("Starting INCR...");
2478 gdk_window_set_events (info->requestor,
2479 gdk_window_get_events (info->requestor) |
2480 GDK_PROPERTY_CHANGE_MASK);
2481 current_incrs = g_list_append (current_incrs, info);
2482 gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
2485 /* If it was a MULTIPLE request, set the property to indicate which
2486 conversions succeeded */
2487 if (event->target == gtk_selection_atoms[MULTIPLE])
2489 GdkAtom *mult_atoms = g_new (GdkAtom, 2 * info->num_conversions);
2490 for (i = 0; i < info->num_conversions; i++)
2492 mult_atoms[2*i] = info->conversions[i].target;
2493 mult_atoms[2*i+1] = info->conversions[i].property;
2496 gdk_property_change (info->requestor, event->property,
2497 gdk_atom_intern_static_string ("ATOM_PAIR"), 32,
2498 GDK_PROP_MODE_REPLACE,
2499 (guchar *)mult_atoms, 2*info->num_conversions);
2500 g_free (mult_atoms);
2503 if (info->num_conversions == 1 &&
2504 info->conversions[0].property == GDK_NONE)
2506 /* Reject the entire conversion */
2507 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2516 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2524 if (info->num_incrs == 0)
2526 g_free (info->conversions);
2527 g_slice_free (GtkIncrInfo, info);
2530 g_object_unref (widget);
2535 /*************************************************************
2536 * _gtk_selection_incr_event:
2537 * Called whenever an PropertyNotify event occurs for an
2538 * GdkWindow with user_data == NULL. These will be notifications
2539 * that a window we are sending the selection to via the
2540 * INCR protocol has deleted a property and is ready for
2544 * window: the requestor window
2545 * event: the property event structure
2548 *************************************************************/
2551 _gtk_selection_incr_event (GdkWindow *window,
2552 GdkEventProperty *event)
2555 GtkIncrInfo *info = NULL;
2558 gulong selection_max_size;
2562 if (event->state != GDK_PROPERTY_DELETE)
2565 #ifdef DEBUG_SELECTION
2566 g_message ("PropertyDelete, property %ld", event->atom);
2569 selection_max_size = GTK_SELECTION_MAX_SIZE (gdk_window_get_display (window));
2571 /* Now find the appropriate ongoing INCR */
2572 tmp_list = current_incrs;
2575 info = (GtkIncrInfo *)tmp_list->data;
2576 if (info->requestor == event->window)
2579 tmp_list = tmp_list->next;
2582 if (tmp_list == NULL)
2585 /* Find out which target this is for */
2586 for (i=0; i<info->num_conversions; i++)
2588 if (info->conversions[i].property == event->atom &&
2589 info->conversions[i].offset != -1)
2593 info->idle_time = 0;
2595 if (info->conversions[i].offset == -2) /* only the last 0-length
2603 num_bytes = info->conversions[i].data.length -
2604 info->conversions[i].offset;
2605 buffer = info->conversions[i].data.data +
2606 info->conversions[i].offset;
2608 if (num_bytes > selection_max_size)
2610 num_bytes = selection_max_size;
2611 info->conversions[i].offset += selection_max_size;
2614 info->conversions[i].offset = -2;
2616 #ifdef DEBUG_SELECTION
2617 g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",
2618 num_bytes, info->conversions[i].offset,
2619 GDK_WINDOW_XID(info->requestor), event->atom);
2622 bytes_per_item = gtk_selection_bytes_per_item (info->conversions[i].data.format);
2623 gdk_property_change (info->requestor, event->atom,
2624 info->conversions[i].data.type,
2625 info->conversions[i].data.format,
2626 GDK_PROP_MODE_REPLACE,
2628 num_bytes / bytes_per_item);
2630 if (info->conversions[i].offset == -2)
2632 g_free (info->conversions[i].data.data);
2633 info->conversions[i].data.data = NULL;
2639 info->conversions[i].offset = -1;
2644 /* Check if we're finished with all the targets */
2646 if (info->num_incrs == 0)
2648 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2649 g_list_free (tmp_list);
2650 /* Let the timeout free it */
2656 /*************************************************************
2657 * gtk_selection_incr_timeout:
2658 * Timeout callback for the sending portion of the INCR
2661 * info: Information about this incr
2663 *************************************************************/
2666 gtk_selection_incr_timeout (GtkIncrInfo *info)
2671 /* Determine if retrieval has finished by checking if it still in
2672 list of pending retrievals */
2674 tmp_list = current_incrs;
2677 if (info == (GtkIncrInfo *)tmp_list->data)
2679 tmp_list = tmp_list->next;
2682 /* If retrieval is finished */
2683 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2685 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2687 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2688 g_list_free (tmp_list);
2691 g_free (info->conversions);
2692 /* FIXME: we should check if requestor window is still in use,
2693 and if not, remove it? */
2695 g_slice_free (GtkIncrInfo, info);
2697 retval = FALSE; /* remove timeout */
2703 retval = TRUE; /* timeout will happen again */
2709 /*************************************************************
2710 * _gtk_selection_notify:
2711 * Handler for "selection-notify-event" signals on windows
2712 * where a retrieval is currently in process. The selection
2713 * owner has responded to our conversion request.
2715 * widget: Widget getting signal
2716 * event: Selection event structure
2717 * info: Information about this retrieval
2719 * was event handled?
2720 *************************************************************/
2723 _gtk_selection_notify (GtkWidget *widget,
2724 GdkEventSelection *event)
2727 GtkRetrievalInfo *info = NULL;
2729 guchar *buffer = NULL;
2734 #ifdef DEBUG_SELECTION
2735 g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",
2736 event->selection, event->target, event->property);
2739 window = gtk_widget_get_window (widget);
2741 tmp_list = current_retrievals;
2744 info = (GtkRetrievalInfo *)tmp_list->data;
2745 if (info->widget == widget && info->selection == event->selection)
2747 tmp_list = tmp_list->next;
2750 if (!tmp_list) /* no retrieval in progress */
2753 if (event->property != GDK_NONE)
2754 length = gdk_selection_property_get (window, &buffer,
2757 length = 0; /* silence gcc */
2759 if (event->property == GDK_NONE || buffer == NULL)
2761 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2762 g_list_free (tmp_list);
2763 /* structure will be freed in timeout */
2764 gtk_selection_retrieval_report (info,
2765 GDK_NONE, 0, NULL, -1, event->time);
2770 if (type == gtk_selection_atoms[INCR])
2772 /* The remainder of the selection will come through PropertyNotify
2775 info->notify_time = event->time;
2776 info->idle_time = 0;
2777 info->offset = 0; /* Mark as OK to proceed */
2778 gdk_window_set_events (window,
2779 gdk_window_get_events (window)
2780 | GDK_PROPERTY_CHANGE_MASK);
2784 /* We don't delete the info structure - that will happen in timeout */
2785 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2786 g_list_free (tmp_list);
2788 info->offset = length;
2789 gtk_selection_retrieval_report (info,
2791 buffer, length, event->time);
2794 gdk_property_delete (window, event->property);
2801 /*************************************************************
2802 * _gtk_selection_property_notify:
2803 * Handler for "property-notify-event" signals on windows
2804 * where a retrieval is currently in process. The selection
2805 * owner has added more data.
2807 * widget: Widget getting signal
2808 * event: Property event structure
2809 * info: Information about this retrieval
2811 * was event handled?
2812 *************************************************************/
2815 _gtk_selection_property_notify (GtkWidget *widget,
2816 GdkEventProperty *event)
2819 GtkRetrievalInfo *info = NULL;
2826 g_return_val_if_fail (widget != NULL, FALSE);
2827 g_return_val_if_fail (event != NULL, FALSE);
2829 #if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
2830 if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
2831 (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
2835 #ifdef DEBUG_SELECTION
2836 g_message ("PropertyNewValue, property %ld",
2840 tmp_list = current_retrievals;
2843 info = (GtkRetrievalInfo *)tmp_list->data;
2844 if (info->widget == widget)
2846 tmp_list = tmp_list->next;
2849 if (!tmp_list) /* No retrieval in progress */
2852 if (info->offset < 0) /* We haven't got the SelectionNotify
2853 for this retrieval yet */
2856 info->idle_time = 0;
2858 window = gtk_widget_get_window (widget);
2859 length = gdk_selection_property_get (window, &new_buffer,
2861 gdk_property_delete (window, event->atom);
2863 /* We could do a lot better efficiency-wise by paying attention to
2864 what length was sent in the initial INCR transaction, instead of
2865 doing memory allocation at every step. But its only guaranteed to
2866 be a _lower bound_ (pretty useless!) */
2868 if (length == 0 || type == GDK_NONE) /* final zero length portion */
2870 /* Info structure will be freed in timeout */
2871 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2872 g_list_free (tmp_list);
2873 gtk_selection_retrieval_report (info,
2875 (type == GDK_NONE) ? NULL : info->buffer,
2876 (type == GDK_NONE) ? -1 : info->offset,
2879 else /* append on newly arrived data */
2883 #ifdef DEBUG_SELECTION
2884 g_message ("Start - Adding %d bytes at offset 0",
2887 info->buffer = new_buffer;
2888 info->offset = length;
2893 #ifdef DEBUG_SELECTION
2894 g_message ("Appending %d bytes at offset %d",
2895 length,info->offset);
2897 /* We copy length+1 bytes to preserve guaranteed null termination */
2898 info->buffer = g_realloc (info->buffer, info->offset+length+1);
2899 memcpy (info->buffer + info->offset, new_buffer, length+1);
2900 info->offset += length;
2901 g_free (new_buffer);
2908 /*************************************************************
2909 * gtk_selection_retrieval_timeout:
2910 * Timeout callback while receiving a selection.
2912 * info: Information about this retrieval
2914 *************************************************************/
2917 gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
2922 /* Determine if retrieval has finished by checking if it still in
2923 list of pending retrievals */
2925 tmp_list = current_retrievals;
2928 if (info == (GtkRetrievalInfo *)tmp_list->data)
2930 tmp_list = tmp_list->next;
2933 /* If retrieval is finished */
2934 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2936 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2938 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2939 g_list_free (tmp_list);
2940 gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
2943 g_free (info->buffer);
2944 g_slice_free (GtkRetrievalInfo, info);
2946 retval = FALSE; /* remove timeout */
2952 retval = TRUE; /* timeout will happen again */
2958 /*************************************************************
2959 * gtk_selection_retrieval_report:
2960 * Emits a "selection-received" signal.
2962 * info: information about the retrieval that completed
2963 * buffer: buffer containing data (NULL => errror)
2964 * time: timestamp for data in buffer
2966 *************************************************************/
2969 gtk_selection_retrieval_report (GtkRetrievalInfo *info,
2970 GdkAtom type, gint format,
2971 guchar *buffer, gint length,
2974 GtkSelectionData data;
2976 data.selection = info->selection;
2977 data.target = info->target;
2979 data.format = format;
2981 data.length = length;
2983 data.display = gtk_widget_get_display (info->widget);
2985 g_signal_emit_by_name (info->widget,
2986 "selection-received",
2990 /*************************************************************
2991 * gtk_selection_invoke_handler:
2992 * Finds and invokes handler for specified
2993 * widget/selection/target combination, calls
2994 * gtk_selection_default_handler if none exists.
2997 * widget: selection owner
2998 * data: selection data [INOUT]
2999 * time: time from requeset
3002 * Number of bytes written to buffer, -1 if error
3003 *************************************************************/
3006 gtk_selection_invoke_handler (GtkWidget *widget,
3007 GtkSelectionData *data,
3010 GtkTargetList *target_list;
3014 g_return_if_fail (widget != NULL);
3016 target_list = gtk_selection_target_list_get (widget, data->selection);
3017 if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
3019 gtk_target_list_find (target_list, data->target, &info))
3021 g_signal_emit_by_name (widget,
3027 gtk_selection_default_handler (widget, data);
3030 /*************************************************************
3031 * gtk_selection_default_handler:
3032 * Handles some default targets that exist for any widget
3033 * If it can't fit results into buffer, returns -1. This
3034 * won't happen in any conceivable case, since it would
3035 * require 1000 selection targets!
3038 * widget: selection owner
3039 * data: selection data [INOUT]
3041 *************************************************************/
3044 gtk_selection_default_handler (GtkWidget *widget,
3045 GtkSelectionData *data)
3047 if (data->target == gtk_selection_atoms[TIMESTAMP])
3049 /* Time which was used to obtain selection */
3051 GtkSelectionInfo *selection_info;
3053 tmp_list = current_selections;
3056 selection_info = (GtkSelectionInfo *)tmp_list->data;
3057 if ((selection_info->widget == widget) &&
3058 (selection_info->selection == data->selection))
3060 gulong time = selection_info->time;
3062 gtk_selection_data_set (data,
3063 GDK_SELECTION_TYPE_INTEGER,
3070 tmp_list = tmp_list->next;
3075 else if (data->target == gtk_selection_atoms[TARGETS])
3077 /* List of all targets supported for this widget/selection pair */
3081 GtkTargetList *target_list;
3082 GtkTargetPair *pair;
3084 target_list = gtk_selection_target_list_get (widget,
3086 count = g_list_length (target_list->list) + 3;
3088 data->type = GDK_SELECTION_TYPE_ATOM;
3090 data->length = count * sizeof (GdkAtom);
3092 /* selection data is always terminated by a trailing \0
3094 p = g_malloc (data->length + 1);
3095 data->data = (guchar *)p;
3096 data->data[data->length] = '\0';
3098 *p++ = gtk_selection_atoms[TIMESTAMP];
3099 *p++ = gtk_selection_atoms[TARGETS];
3100 *p++ = gtk_selection_atoms[MULTIPLE];
3102 tmp_list = target_list->list;
3105 pair = (GtkTargetPair *)tmp_list->data;
3106 *p++ = pair->target;
3108 tmp_list = tmp_list->next;
3111 else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
3113 gtk_selection_data_set (data,
3114 gdk_atom_intern_static_string ("NULL"),
3125 * gtk_selection_data_copy:
3126 * @data: a pointer to a #GtkSelectionData structure.
3128 * Makes a copy of a #GtkSelectionData structure and its data.
3130 * Return value: a pointer to a copy of @data.
3133 gtk_selection_data_copy (const GtkSelectionData *data)
3135 GtkSelectionData *new_data;
3137 g_return_val_if_fail (data != NULL, NULL);
3139 new_data = g_slice_new (GtkSelectionData);
3144 new_data->data = g_malloc (data->length + 1);
3145 memcpy (new_data->data, data->data, data->length + 1);
3152 * gtk_selection_data_free:
3153 * @data: a pointer to a #GtkSelectionData structure.
3155 * Frees a #GtkSelectionData structure returned from
3156 * gtk_selection_data_copy().
3159 gtk_selection_data_free (GtkSelectionData *data)
3161 g_return_if_fail (data != NULL);
3163 g_free (data->data);
3165 g_slice_free (GtkSelectionData, data);
3169 * gtk_target_entry_new:
3170 * @target: String identifier for target
3171 * @flags: Set of flags, see #GtkTargetFlags
3172 * @info: an ID that will be passed back to the application
3174 * Makes a new #GtkTargetEntry structure.
3176 * Return value: a pointer to a new GtkTargetEntry structure.
3177 * Free with gtk_target_entry_free()
3180 gtk_target_entry_new (const char *target,
3184 GtkTargetEntry entry = { (char *) target, flags, info };
3185 return gtk_target_entry_copy (&entry);
3189 * gtk_target_entry_copy:
3190 * @data: a pointer to a #GtkTargetEntry structure.
3192 * Makes a copy of a #GtkTargetEntry structure and its data.
3194 * Return value: a pointer to a copy of @data.
3195 * Free with gtk_target_entry_free()
3198 gtk_target_entry_copy (GtkTargetEntry *data)
3200 GtkTargetEntry *new_data;
3202 g_return_val_if_fail (data != NULL, NULL);
3204 new_data = g_slice_new (GtkTargetEntry);
3205 new_data->target = g_strdup (data->target);
3206 new_data->flags = data->flags;
3207 new_data->info = data->info;
3213 * gtk_target_entry_free:
3214 * @data: a pointer to a #GtkTargetEntry structure.
3216 * Frees a #GtkTargetEntry structure returned from
3217 * gtk_target_entry_new() or gtk_target_entry_copy().
3220 gtk_target_entry_free (GtkTargetEntry *data)
3222 g_return_if_fail (data != NULL);
3224 g_free (data->target);
3226 g_slice_free (GtkTargetEntry, data);
3230 G_DEFINE_BOXED_TYPE (GtkSelectionData, gtk_selection_data,
3231 gtk_selection_data_copy,
3232 gtk_selection_data_free)
3234 G_DEFINE_BOXED_TYPE (GtkTargetList, gtk_target_list,
3235 gtk_target_list_ref,
3236 gtk_target_list_unref)
3238 G_DEFINE_BOXED_TYPE (GtkTargetEntry, gtk_target_entry,
3239 gtk_target_entry_copy,
3240 gtk_target_entry_free)
3243 gtk_selection_bytes_per_item (gint format)
3248 return sizeof (char);
3251 return sizeof (short);
3254 return sizeof (long);
3257 g_assert_not_reached();