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: 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: 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: 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: 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: 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: 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: 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;
1102 selection_data.selection = selection;
1103 selection_data.target = target;
1104 selection_data.data = NULL;
1105 selection_data.length = -1;
1106 selection_data.display = display;
1108 gdk_window_get_user_data (owner_window, &owner_widget_ptr);
1109 owner_widget = owner_widget_ptr;
1111 if (owner_widget != NULL)
1113 gtk_selection_invoke_handler (owner_widget,
1117 gtk_selection_retrieval_report (info,
1118 selection_data.type,
1119 selection_data.format,
1120 selection_data.data,
1121 selection_data.length,
1124 g_free (selection_data.data);
1125 selection_data.data = NULL;
1126 selection_data.length = -1;
1128 g_slice_free (GtkRetrievalInfo, info);
1133 /* Otherwise, we need to go through X */
1135 current_retrievals = g_list_append (current_retrievals, info);
1136 gdk_selection_convert (gtk_widget_get_window (widget), selection, target, time_);
1137 gdk_threads_add_timeout (1000,
1138 (GSourceFunc) gtk_selection_retrieval_timeout, info);
1144 * gtk_selection_data_get_selection:
1145 * @selection_data: a pointer to a #GtkSelectionData structure.
1147 * Retrieves the selection #GdkAtom of the selection data.
1149 * Returns: the selection #GdkAtom of the selection data.
1154 gtk_selection_data_get_selection (const GtkSelectionData *selection_data)
1156 g_return_val_if_fail (selection_data != NULL, 0);
1158 return selection_data->selection;
1162 * gtk_selection_data_get_target:
1163 * @selection_data: a pointer to a #GtkSelectionData structure.
1165 * Retrieves the target of the selection.
1167 * Returns: the target of the selection.
1172 gtk_selection_data_get_target (const GtkSelectionData *selection_data)
1174 g_return_val_if_fail (selection_data != NULL, 0);
1176 return selection_data->target;
1180 * gtk_selection_data_get_data_type:
1181 * @selection_data: a pointer to a #GtkSelectionData structure.
1183 * Retrieves the data type of the selection.
1185 * Returns: the data type of the selection.
1190 gtk_selection_data_get_data_type (const GtkSelectionData *selection_data)
1192 g_return_val_if_fail (selection_data != NULL, 0);
1194 return selection_data->type;
1198 * gtk_selection_data_get_format:
1199 * @selection_data: a pointer to a #GtkSelectionData structure.
1201 * Retrieves the format of the selection.
1203 * Returns: the format of the selection.
1208 gtk_selection_data_get_format (const GtkSelectionData *selection_data)
1210 g_return_val_if_fail (selection_data != NULL, 0);
1212 return selection_data->format;
1216 * gtk_selection_data_get_data: (skip)
1217 * @selection_data: a pointer to a #GtkSelectionData structure.
1219 * Retrieves the raw data of the selection.
1221 * Returns: the raw data of the selection.
1226 gtk_selection_data_get_data (const GtkSelectionData *selection_data)
1228 g_return_val_if_fail (selection_data != NULL, NULL);
1230 return selection_data->data;
1234 * gtk_selection_data_get_length:
1235 * @selection_data: a pointer to a #GtkSelectionData structure.
1237 * Retrieves the length of the raw data of the selection.
1239 * Returns: the length of the data of the selection.
1244 gtk_selection_data_get_length (const GtkSelectionData *selection_data)
1246 g_return_val_if_fail (selection_data != NULL, -1);
1248 return selection_data->length;
1252 * gtk_selection_data_get_data_with_length:
1253 * @selection_data: a pointer to a #GtkSelectionData structure
1254 * @length: return location for length of the data segment
1256 * Retrieves the raw data of the selection along with its length.
1258 * Returns: (array length=length): the raw data of the selection
1260 * Rename to: gtk_selection_data_get_data
1264 gtk_selection_data_get_data_with_length (const GtkSelectionData *selection_data,
1267 g_return_val_if_fail (selection_data != NULL, NULL);
1269 *length = selection_data->length;
1271 return selection_data->data;
1275 * gtk_selection_data_get_display:
1276 * @selection_data: a pointer to a #GtkSelectionData structure.
1278 * Retrieves the display of the selection.
1280 * Returns: (transfer none): the display of the selection.
1285 gtk_selection_data_get_display (const GtkSelectionData *selection_data)
1287 g_return_val_if_fail (selection_data != NULL, NULL);
1289 return selection_data->display;
1293 * gtk_selection_data_set:
1294 * @selection_data: a pointer to a #GtkSelectionData structure.
1295 * @type: the type of selection data
1296 * @format: format (number of bits in a unit)
1297 * @data: (array) (element-type guchar): pointer to the data (will be copied)
1298 * @length: length of the data
1300 * Stores new data into a #GtkSelectionData object. Should
1301 * <emphasis>only</emphasis> be called from a selection handler callback.
1302 * Zero-terminates the stored data.
1305 gtk_selection_data_set (GtkSelectionData *selection_data,
1311 g_return_if_fail (selection_data != NULL);
1313 g_free (selection_data->data);
1315 selection_data->type = type;
1316 selection_data->format = format;
1320 selection_data->data = g_new (guchar, length+1);
1321 memcpy (selection_data->data, data, length);
1322 selection_data->data[length] = 0;
1326 g_return_if_fail (length <= 0);
1329 selection_data->data = NULL;
1331 selection_data->data = (guchar *) g_strdup ("");
1334 selection_data->length = length;
1338 selection_set_string (GtkSelectionData *selection_data,
1342 gchar *tmp = g_strndup (str, len);
1343 gchar *latin1 = gdk_utf8_to_string_target (tmp);
1348 gtk_selection_data_set (selection_data,
1349 GDK_SELECTION_TYPE_STRING,
1350 8, (guchar *) latin1, strlen (latin1));
1360 selection_set_compound_text (GtkSelectionData *selection_data,
1369 gboolean result = FALSE;
1371 #ifdef GDK_WINDOWING_X11
1372 if (GDK_IS_X11_DISPLAY (selection_data->display))
1374 tmp = g_strndup (str, len);
1375 if (gdk_x11_display_utf8_to_compound_text (selection_data->display, tmp,
1376 &encoding, &format, &text, &new_length))
1378 gtk_selection_data_set (selection_data, encoding, format, text, new_length);
1379 gdk_x11_free_compound_text (text);
1390 /* Normalize \r and \n into \r\n
1393 normalize_to_crlf (const gchar *str,
1396 GString *result = g_string_sized_new (len);
1397 const gchar *p = str;
1398 const gchar *end = str + len;
1403 g_string_append_c (result, '\r');
1407 g_string_append_c (result, *p);
1409 if (p == end || *p != '\n')
1410 g_string_append_c (result, '\n');
1415 g_string_append_c (result, *p);
1419 return g_string_free (result, FALSE);
1422 /* Normalize \r and \r\n into \n
1425 normalize_to_lf (gchar *str,
1428 GString *result = g_string_sized_new (len);
1429 const gchar *p = str;
1437 g_string_append_c (result, '\n');
1443 g_string_append_c (result, *p);
1447 return g_string_free (result, FALSE);
1451 selection_set_text_plain (GtkSelectionData *selection_data,
1455 const gchar *charset = NULL;
1457 GError *error = NULL;
1459 result = normalize_to_crlf (str, len);
1460 if (selection_data->target == text_plain_atom)
1462 else if (selection_data->target == text_plain_locale_atom)
1463 g_get_charset (&charset);
1467 gchar *tmp = result;
1468 result = g_convert_with_fallback (tmp, -1,
1470 NULL, NULL, NULL, &error);
1476 g_warning ("Error converting from %s to %s: %s",
1477 "UTF-8", charset, error->message);
1478 g_error_free (error);
1483 gtk_selection_data_set (selection_data,
1484 selection_data->target,
1485 8, (guchar *) result, strlen (result));
1492 selection_get_text_plain (const GtkSelectionData *selection_data)
1494 const gchar *charset = NULL;
1495 gchar *str, *result;
1497 GError *error = NULL;
1499 str = g_strdup ((const gchar *) selection_data->data);
1500 len = selection_data->length;
1502 if (selection_data->type == text_plain_atom)
1503 charset = "ISO-8859-1";
1504 else if (selection_data->type == text_plain_locale_atom)
1505 g_get_charset (&charset);
1510 str = g_convert_with_fallback (tmp, len,
1512 NULL, NULL, &len, &error);
1517 g_warning ("Error converting from %s to %s: %s",
1518 charset, "UTF-8", error->message);
1519 g_error_free (error);
1524 else if (!g_utf8_validate (str, -1, NULL))
1526 g_warning ("Error converting from %s to %s: %s",
1527 "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8");
1533 result = normalize_to_lf (str, len);
1536 return (guchar *) result;
1540 * gtk_selection_data_set_text:
1541 * @selection_data: a #GtkSelectionData
1542 * @str: a UTF-8 string
1543 * @len: the length of @str, or -1 if @str is nul-terminated.
1545 * Sets the contents of the selection from a UTF-8 encoded string.
1546 * The string is converted to the form determined by
1547 * @selection_data->target.
1549 * Return value: %TRUE if the selection was successfully set,
1553 gtk_selection_data_set_text (GtkSelectionData *selection_data,
1557 g_return_val_if_fail (selection_data != NULL, FALSE);
1564 if (selection_data->target == utf8_atom)
1566 gtk_selection_data_set (selection_data,
1568 8, (guchar *)str, len);
1571 else if (selection_data->target == GDK_TARGET_STRING)
1573 return selection_set_string (selection_data, str, len);
1575 else if (selection_data->target == ctext_atom ||
1576 selection_data->target == text_atom)
1578 if (selection_set_compound_text (selection_data, str, len))
1580 else if (selection_data->target == text_atom)
1581 return selection_set_string (selection_data, str, len);
1583 else if (selection_data->target == text_plain_atom ||
1584 selection_data->target == text_plain_utf8_atom ||
1585 selection_data->target == text_plain_locale_atom)
1587 return selection_set_text_plain (selection_data, str, len);
1594 * gtk_selection_data_get_text:
1595 * @selection_data: a #GtkSelectionData
1597 * Gets the contents of the selection data as a UTF-8 string.
1599 * Return value: (type utf8): if the selection data contained a
1600 * recognized text type and it could be converted to UTF-8, a newly
1601 * allocated string containing the converted text, otherwise %NULL.
1602 * If the result is non-%NULL it must be freed with g_free().
1605 gtk_selection_data_get_text (const GtkSelectionData *selection_data)
1607 guchar *result = NULL;
1609 g_return_val_if_fail (selection_data != NULL, NULL);
1613 if (selection_data->length >= 0 &&
1614 (selection_data->type == GDK_TARGET_STRING ||
1615 selection_data->type == ctext_atom ||
1616 selection_data->type == utf8_atom))
1620 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1621 selection_data->type,
1622 selection_data->format,
1623 selection_data->data,
1624 selection_data->length,
1627 result = (guchar *) list[0];
1629 for (i = 1; i < count; i++)
1633 else if (selection_data->length >= 0 &&
1634 (selection_data->type == text_plain_atom ||
1635 selection_data->type == text_plain_utf8_atom ||
1636 selection_data->type == text_plain_locale_atom))
1638 result = selection_get_text_plain (selection_data);
1645 * gtk_selection_data_set_pixbuf:
1646 * @selection_data: a #GtkSelectionData
1647 * @pixbuf: a #GdkPixbuf
1649 * Sets the contents of the selection from a #GdkPixbuf
1650 * The pixbuf is converted to the form determined by
1651 * @selection_data->target.
1653 * Return value: %TRUE if the selection was successfully set,
1659 gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
1662 GSList *formats, *f;
1669 g_return_val_if_fail (selection_data != NULL, FALSE);
1670 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
1672 formats = gdk_pixbuf_get_formats ();
1674 for (f = formats; f; f = f->next)
1676 GdkPixbufFormat *fmt = f->data;
1678 mimes = gdk_pixbuf_format_get_mime_types (fmt);
1679 for (m = mimes; *m; m++)
1681 atom = gdk_atom_intern (*m, FALSE);
1682 if (selection_data->target == atom)
1685 type = gdk_pixbuf_format_get_name (fmt);
1686 result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len,
1688 ((strcmp (type, "png") == 0) ?
1689 "compression" : NULL), "2",
1692 gtk_selection_data_set (selection_data,
1693 atom, 8, (guchar *)str, len);
1697 g_slist_free (formats);
1706 g_slist_free (formats);
1712 * gtk_selection_data_get_pixbuf:
1713 * @selection_data: a #GtkSelectionData
1715 * Gets the contents of the selection data as a #GdkPixbuf.
1717 * Return value: (transfer full): if the selection data contained a recognized
1718 * image type and it could be converted to a #GdkPixbuf, a
1719 * newly allocated pixbuf is returned, otherwise %NULL.
1720 * If the result is non-%NULL it must be freed with g_object_unref().
1725 gtk_selection_data_get_pixbuf (const GtkSelectionData *selection_data)
1727 GdkPixbufLoader *loader;
1728 GdkPixbuf *result = NULL;
1730 g_return_val_if_fail (selection_data != NULL, NULL);
1732 if (selection_data->length > 0)
1734 loader = gdk_pixbuf_loader_new ();
1736 gdk_pixbuf_loader_write (loader,
1737 selection_data->data,
1738 selection_data->length,
1740 gdk_pixbuf_loader_close (loader, NULL);
1741 result = gdk_pixbuf_loader_get_pixbuf (loader);
1744 g_object_ref (result);
1746 g_object_unref (loader);
1753 * gtk_selection_data_set_uris:
1754 * @selection_data: a #GtkSelectionData
1755 * @uris: a %NULL-terminated array of 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: location to store an array of targets. The result
1856 * stored here must be freed with g_free().
1857 * @n_atoms: location to store number of items in @targets.
1859 * Gets the contents of @selection_data as an array of targets.
1860 * This can be used to interpret the results of getting
1861 * the standard TARGETS target that is always supplied for
1864 * Return value: %TRUE if @selection_data contains a valid
1865 * array of targets, otherwise %FALSE.
1868 gtk_selection_data_get_targets (const GtkSelectionData *selection_data,
1872 g_return_val_if_fail (selection_data != NULL, FALSE);
1874 if (selection_data->length >= 0 &&
1875 selection_data->format == 32 &&
1876 selection_data->type == GDK_SELECTION_TYPE_ATOM)
1879 *targets = g_memdup (selection_data->data, selection_data->length);
1881 *n_atoms = selection_data->length / sizeof (GdkAtom);
1897 * gtk_targets_include_text:
1898 * @targets: an array of #GdkAtom<!-- -->s
1899 * @n_targets: the length of @targets
1901 * Determines if any of the targets in @targets can be used to
1904 * Return value: %TRUE if @targets include a suitable target for text,
1910 gtk_targets_include_text (GdkAtom *targets,
1914 gboolean result = FALSE;
1916 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1918 /* Keep in sync with gtk_target_list_add_text_targets()
1923 for (i = 0; i < n_targets; i++)
1925 if (targets[i] == utf8_atom ||
1926 targets[i] == text_atom ||
1927 targets[i] == GDK_TARGET_STRING ||
1928 targets[i] == ctext_atom ||
1929 targets[i] == text_plain_atom ||
1930 targets[i] == text_plain_utf8_atom ||
1931 targets[i] == text_plain_locale_atom)
1942 * gtk_targets_include_rich_text:
1943 * @targets: an array of #GdkAtom<!-- -->s
1944 * @n_targets: the length of @targets
1945 * @buffer: a #GtkTextBuffer
1947 * Determines if any of the targets in @targets can be used to
1948 * provide rich text.
1950 * Return value: %TRUE if @targets include a suitable target for rich text,
1956 gtk_targets_include_rich_text (GdkAtom *targets,
1958 GtkTextBuffer *buffer)
1960 GdkAtom *rich_targets;
1961 gint n_rich_targets;
1963 gboolean result = FALSE;
1965 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1966 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1970 rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
1973 for (i = 0; i < n_targets; i++)
1975 for (j = 0; j < n_rich_targets; j++)
1977 if (targets[i] == rich_targets[j])
1986 g_free (rich_targets);
1992 * gtk_selection_data_targets_include_text:
1993 * @selection_data: a #GtkSelectionData object
1995 * Given a #GtkSelectionData object holding a list of targets,
1996 * determines if any of the targets in @targets can be used to
1999 * Return value: %TRUE if @selection_data holds a list of targets,
2000 * and a suitable target for text is included, otherwise %FALSE.
2003 gtk_selection_data_targets_include_text (const GtkSelectionData *selection_data)
2007 gboolean result = FALSE;
2009 g_return_val_if_fail (selection_data != NULL, FALSE);
2013 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2015 result = gtk_targets_include_text (targets, n_targets);
2023 * gtk_selection_data_targets_include_rich_text:
2024 * @selection_data: a #GtkSelectionData object
2025 * @buffer: a #GtkTextBuffer
2027 * Given a #GtkSelectionData object holding a list of targets,
2028 * determines if any of the targets in @targets can be used to
2029 * provide rich text.
2031 * Return value: %TRUE if @selection_data holds a list of targets,
2032 * and a suitable target for rich text is included,
2038 gtk_selection_data_targets_include_rich_text (const GtkSelectionData *selection_data,
2039 GtkTextBuffer *buffer)
2043 gboolean result = FALSE;
2045 g_return_val_if_fail (selection_data != NULL, FALSE);
2046 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2050 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2052 result = gtk_targets_include_rich_text (targets, n_targets, buffer);
2060 * gtk_targets_include_image:
2061 * @targets: an array of #GdkAtom<!-- -->s
2062 * @n_targets: the length of @targets
2063 * @writable: whether to accept only targets for which GTK+ knows
2064 * how to convert a pixbuf into the format
2066 * Determines if any of the targets in @targets can be used to
2067 * provide a #GdkPixbuf.
2069 * Return value: %TRUE if @targets include a suitable target for images,
2075 gtk_targets_include_image (GdkAtom *targets,
2079 GtkTargetList *list;
2082 gboolean result = FALSE;
2084 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2086 list = gtk_target_list_new (NULL, 0);
2087 gtk_target_list_add_image_targets (list, 0, writable);
2088 for (i = 0; i < n_targets && !result; i++)
2090 for (l = list->list; l; l = l->next)
2092 GtkTargetPair *pair = (GtkTargetPair *)l->data;
2093 if (pair->target == targets[i])
2100 gtk_target_list_unref (list);
2106 * gtk_selection_data_targets_include_image:
2107 * @selection_data: a #GtkSelectionData object
2108 * @writable: whether to accept only targets for which GTK+ knows
2109 * how to convert a pixbuf into the format
2111 * Given a #GtkSelectionData object holding a list of targets,
2112 * determines if any of the targets in @targets can be used to
2113 * provide a #GdkPixbuf.
2115 * Return value: %TRUE if @selection_data holds a list of targets,
2116 * and a suitable target for images is included, otherwise %FALSE.
2121 gtk_selection_data_targets_include_image (const GtkSelectionData *selection_data,
2126 gboolean result = FALSE;
2128 g_return_val_if_fail (selection_data != NULL, FALSE);
2132 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2134 result = gtk_targets_include_image (targets, n_targets, writable);
2142 * gtk_targets_include_uri:
2143 * @targets: an array of #GdkAtom<!-- -->s
2144 * @n_targets: the length of @targets
2146 * Determines if any of the targets in @targets can be used to
2147 * provide an uri list.
2149 * Return value: %TRUE if @targets include a suitable target for uri lists,
2155 gtk_targets_include_uri (GdkAtom *targets,
2159 gboolean result = FALSE;
2161 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2163 /* Keep in sync with gtk_target_list_add_uri_targets()
2168 for (i = 0; i < n_targets; i++)
2170 if (targets[i] == text_uri_list_atom)
2181 * gtk_selection_data_targets_include_uri:
2182 * @selection_data: a #GtkSelectionData object
2184 * Given a #GtkSelectionData object holding a list of targets,
2185 * determines if any of the targets in @targets can be used to
2186 * provide a list or URIs.
2188 * Return value: %TRUE if @selection_data holds a list of targets,
2189 * and a suitable target for URI lists is included, otherwise %FALSE.
2194 gtk_selection_data_targets_include_uri (const GtkSelectionData *selection_data)
2198 gboolean result = FALSE;
2200 g_return_val_if_fail (selection_data != NULL, FALSE);
2204 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2206 result = gtk_targets_include_uri (targets, n_targets);
2214 /*************************************************************
2215 * gtk_selection_init:
2216 * Initialize local variables
2220 *************************************************************/
2223 gtk_selection_init (void)
2225 gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
2226 gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
2227 gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
2228 gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
2229 gtk_selection_atoms[SAVE_TARGETS] = gdk_atom_intern_static_string ("SAVE_TARGETS");
2235 * _gtk_selection_clear:
2236 * @widget: a #GtkWidget
2239 * The default handler for the #GtkWidget::selection-clear-event
2242 * Return value: %TRUE if the event was handled, otherwise false
2245 _gtk_selection_clear (GtkWidget *widget,
2246 GdkEventSelection *event)
2248 /* Note that we filter clear events in gdkselection-x11.c, so
2249 * that we only will get here if the clear event actually
2250 * represents a change that we didn't do ourself.
2253 GtkSelectionInfo *selection_info = NULL;
2255 tmp_list = current_selections;
2258 selection_info = (GtkSelectionInfo *)tmp_list->data;
2260 if ((selection_info->selection == event->selection) &&
2261 (selection_info->widget == widget))
2264 tmp_list = tmp_list->next;
2269 current_selections = g_list_remove_link (current_selections, tmp_list);
2270 g_list_free (tmp_list);
2271 g_slice_free (GtkSelectionInfo, selection_info);
2278 /*************************************************************
2279 * _gtk_selection_request:
2280 * Handler for "selection_request_event"
2285 *************************************************************/
2288 _gtk_selection_request (GtkWidget *widget,
2289 GdkEventSelection *event)
2291 GdkDisplay *display = gtk_widget_get_display (widget);
2295 gulong selection_max_size;
2298 gtk_selection_init ();
2300 selection_max_size = GTK_SELECTION_MAX_SIZE (display);
2302 /* Check if we own selection */
2304 tmp_list = current_selections;
2307 GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
2309 if ((selection_info->selection == event->selection) &&
2310 (selection_info->widget == widget))
2313 tmp_list = tmp_list->next;
2316 if (tmp_list == NULL)
2319 info = g_slice_new (GtkIncrInfo);
2321 g_object_ref (widget);
2323 info->selection = event->selection;
2324 info->num_incrs = 0;
2326 /* Create GdkWindow structure for the requestor */
2328 #ifdef GDK_WINDOWING_X11
2329 if (GDK_IS_X11_DISPLAY (display))
2330 info->requestor = gdk_x11_window_foreign_new_for_display (display, event->requestor);
2333 info->requestor = NULL;
2335 /* Determine conversions we need to perform */
2336 if (event->target == gtk_selection_atoms[MULTIPLE])
2345 gdk_error_trap_push ();
2346 if (!gdk_property_get (info->requestor, event->property, GDK_NONE, /* AnyPropertyType */
2347 0, selection_max_size, FALSE,
2348 &type, &format, &length, &mult_atoms))
2350 gdk_selection_send_notify_for_display (display,
2356 g_free (mult_atoms);
2357 g_slice_free (GtkIncrInfo, info);
2358 gdk_error_trap_pop_ignored ();
2361 gdk_error_trap_pop_ignored ();
2363 /* This is annoying; the ICCCM doesn't specify the property type
2364 * used for the property contents, so the autoconversion for
2365 * ATOM / ATOM_PAIR in GDK doesn't work properly.
2367 #ifdef GDK_WINDOWING_X11
2368 if (type != GDK_SELECTION_TYPE_ATOM &&
2369 type != gdk_atom_intern_static_string ("ATOM_PAIR"))
2371 info->num_conversions = length / (2*sizeof (glong));
2372 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2374 for (i=0; i<info->num_conversions; i++)
2376 info->conversions[i].target = gdk_x11_xatom_to_atom_for_display (display,
2377 ((glong *)mult_atoms)[2*i]);
2378 info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
2379 ((glong *)mult_atoms)[2*i + 1]);
2382 g_free (mult_atoms);
2387 info->num_conversions = length / (2*sizeof (GdkAtom));
2388 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2390 for (i=0; i<info->num_conversions; i++)
2392 info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
2393 info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
2396 g_free (mult_atoms);
2399 else /* only a single conversion */
2401 info->conversions = g_new (GtkIncrConversion, 1);
2402 info->num_conversions = 1;
2403 info->conversions[0].target = event->target;
2404 info->conversions[0].property = event->property;
2407 /* Loop through conversions and determine which of these are big
2408 enough to require doing them via INCR */
2409 for (i=0; i<info->num_conversions; i++)
2411 GtkSelectionData data;
2414 data.selection = event->selection;
2415 data.target = info->conversions[i].target;
2418 data.display = gtk_widget_get_display (widget);
2420 #ifdef DEBUG_SELECTION
2421 g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
2423 info->conversions[i].target,
2424 gdk_atom_name (info->conversions[i].target),
2425 event->requestor, info->conversions[i].property);
2428 gtk_selection_invoke_handler (widget, &data, event->time);
2429 if (data.length < 0)
2431 info->conversions[i].property = GDK_NONE;
2435 g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE);
2437 items = data.length / gtk_selection_bytes_per_item (data.format);
2439 if (data.length > selection_max_size)
2441 /* Sending via INCR */
2442 #ifdef DEBUG_SELECTION
2443 g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n",
2444 data.length, selection_max_size);
2447 info->conversions[i].offset = 0;
2448 info->conversions[i].data = data;
2451 gdk_property_change (info->requestor,
2452 info->conversions[i].property,
2453 gtk_selection_atoms[INCR],
2455 GDK_PROP_MODE_REPLACE,
2456 (guchar *)&items, 1);
2460 info->conversions[i].offset = -1;
2462 gdk_property_change (info->requestor,
2463 info->conversions[i].property,
2466 GDK_PROP_MODE_REPLACE,
2473 /* If we have some INCR's, we need to send the rest of the data in
2476 if (info->num_incrs > 0)
2478 /* FIXME: this could be dangerous if window doesn't still
2481 #ifdef DEBUG_SELECTION
2482 g_message ("Starting INCR...");
2485 gdk_window_set_events (info->requestor,
2486 gdk_window_get_events (info->requestor) |
2487 GDK_PROPERTY_CHANGE_MASK);
2488 current_incrs = g_list_append (current_incrs, info);
2489 gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
2492 /* If it was a MULTIPLE request, set the property to indicate which
2493 conversions succeeded */
2494 if (event->target == gtk_selection_atoms[MULTIPLE])
2496 GdkAtom *mult_atoms = g_new (GdkAtom, 2 * info->num_conversions);
2497 for (i = 0; i < info->num_conversions; i++)
2499 mult_atoms[2*i] = info->conversions[i].target;
2500 mult_atoms[2*i+1] = info->conversions[i].property;
2503 gdk_property_change (info->requestor, event->property,
2504 gdk_atom_intern_static_string ("ATOM_PAIR"), 32,
2505 GDK_PROP_MODE_REPLACE,
2506 (guchar *)mult_atoms, 2*info->num_conversions);
2507 g_free (mult_atoms);
2510 if (info->num_conversions == 1 &&
2511 info->conversions[0].property == GDK_NONE)
2513 /* Reject the entire conversion */
2514 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2523 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2531 if (info->num_incrs == 0)
2533 g_free (info->conversions);
2534 g_slice_free (GtkIncrInfo, info);
2537 g_object_unref (widget);
2542 /*************************************************************
2543 * _gtk_selection_incr_event:
2544 * Called whenever an PropertyNotify event occurs for an
2545 * GdkWindow with user_data == NULL. These will be notifications
2546 * that a window we are sending the selection to via the
2547 * INCR protocol has deleted a property and is ready for
2551 * window: the requestor window
2552 * event: the property event structure
2555 *************************************************************/
2558 _gtk_selection_incr_event (GdkWindow *window,
2559 GdkEventProperty *event)
2562 GtkIncrInfo *info = NULL;
2565 gulong selection_max_size;
2569 if (event->state != GDK_PROPERTY_DELETE)
2572 #ifdef DEBUG_SELECTION
2573 g_message ("PropertyDelete, property %ld", event->atom);
2576 selection_max_size = GTK_SELECTION_MAX_SIZE (gdk_window_get_display (window));
2578 /* Now find the appropriate ongoing INCR */
2579 tmp_list = current_incrs;
2582 info = (GtkIncrInfo *)tmp_list->data;
2583 if (info->requestor == event->window)
2586 tmp_list = tmp_list->next;
2589 if (tmp_list == NULL)
2592 /* Find out which target this is for */
2593 for (i=0; i<info->num_conversions; i++)
2595 if (info->conversions[i].property == event->atom &&
2596 info->conversions[i].offset != -1)
2600 info->idle_time = 0;
2602 if (info->conversions[i].offset == -2) /* only the last 0-length
2610 num_bytes = info->conversions[i].data.length -
2611 info->conversions[i].offset;
2612 buffer = info->conversions[i].data.data +
2613 info->conversions[i].offset;
2615 if (num_bytes > selection_max_size)
2617 num_bytes = selection_max_size;
2618 info->conversions[i].offset += selection_max_size;
2621 info->conversions[i].offset = -2;
2623 #ifdef DEBUG_SELECTION
2624 g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",
2625 num_bytes, info->conversions[i].offset,
2626 GDK_WINDOW_XID(info->requestor), event->atom);
2629 bytes_per_item = gtk_selection_bytes_per_item (info->conversions[i].data.format);
2630 gdk_property_change (info->requestor, event->atom,
2631 info->conversions[i].data.type,
2632 info->conversions[i].data.format,
2633 GDK_PROP_MODE_REPLACE,
2635 num_bytes / bytes_per_item);
2637 if (info->conversions[i].offset == -2)
2639 g_free (info->conversions[i].data.data);
2640 info->conversions[i].data.data = NULL;
2646 info->conversions[i].offset = -1;
2651 /* Check if we're finished with all the targets */
2653 if (info->num_incrs == 0)
2655 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2656 g_list_free (tmp_list);
2657 /* Let the timeout free it */
2663 /*************************************************************
2664 * gtk_selection_incr_timeout:
2665 * Timeout callback for the sending portion of the INCR
2668 * info: Information about this incr
2670 *************************************************************/
2673 gtk_selection_incr_timeout (GtkIncrInfo *info)
2678 /* Determine if retrieval has finished by checking if it still in
2679 list of pending retrievals */
2681 tmp_list = current_incrs;
2684 if (info == (GtkIncrInfo *)tmp_list->data)
2686 tmp_list = tmp_list->next;
2689 /* If retrieval is finished */
2690 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2692 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2694 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2695 g_list_free (tmp_list);
2698 g_free (info->conversions);
2699 /* FIXME: we should check if requestor window is still in use,
2700 and if not, remove it? */
2702 g_slice_free (GtkIncrInfo, info);
2704 retval = FALSE; /* remove timeout */
2710 retval = TRUE; /* timeout will happen again */
2716 /*************************************************************
2717 * _gtk_selection_notify:
2718 * Handler for "selection-notify-event" signals on windows
2719 * where a retrieval is currently in process. The selection
2720 * owner has responded to our conversion request.
2722 * widget: Widget getting signal
2723 * event: Selection event structure
2724 * info: Information about this retrieval
2726 * was event handled?
2727 *************************************************************/
2730 _gtk_selection_notify (GtkWidget *widget,
2731 GdkEventSelection *event)
2734 GtkRetrievalInfo *info = NULL;
2736 guchar *buffer = NULL;
2741 #ifdef DEBUG_SELECTION
2742 g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",
2743 event->selection, event->target, event->property);
2746 window = gtk_widget_get_window (widget);
2748 tmp_list = current_retrievals;
2751 info = (GtkRetrievalInfo *)tmp_list->data;
2752 if (info->widget == widget && info->selection == event->selection)
2754 tmp_list = tmp_list->next;
2757 if (!tmp_list) /* no retrieval in progress */
2760 if (event->property != GDK_NONE)
2761 length = gdk_selection_property_get (window, &buffer,
2764 length = 0; /* silence gcc */
2766 if (event->property == GDK_NONE || buffer == NULL)
2768 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2769 g_list_free (tmp_list);
2770 /* structure will be freed in timeout */
2771 gtk_selection_retrieval_report (info,
2772 GDK_NONE, 0, NULL, -1, event->time);
2777 if (type == gtk_selection_atoms[INCR])
2779 /* The remainder of the selection will come through PropertyNotify
2782 info->notify_time = event->time;
2783 info->idle_time = 0;
2784 info->offset = 0; /* Mark as OK to proceed */
2785 gdk_window_set_events (window,
2786 gdk_window_get_events (window)
2787 | GDK_PROPERTY_CHANGE_MASK);
2791 /* We don't delete the info structure - that will happen in timeout */
2792 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2793 g_list_free (tmp_list);
2795 info->offset = length;
2796 gtk_selection_retrieval_report (info,
2798 buffer, length, event->time);
2801 gdk_property_delete (window, event->property);
2808 /*************************************************************
2809 * _gtk_selection_property_notify:
2810 * Handler for "property-notify-event" signals on windows
2811 * where a retrieval is currently in process. The selection
2812 * owner has added more data.
2814 * widget: Widget getting signal
2815 * event: Property event structure
2816 * info: Information about this retrieval
2818 * was event handled?
2819 *************************************************************/
2822 _gtk_selection_property_notify (GtkWidget *widget,
2823 GdkEventProperty *event)
2826 GtkRetrievalInfo *info = NULL;
2833 g_return_val_if_fail (widget != NULL, FALSE);
2834 g_return_val_if_fail (event != NULL, FALSE);
2836 #if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
2837 if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
2838 (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
2842 #ifdef DEBUG_SELECTION
2843 g_message ("PropertyNewValue, property %ld",
2847 tmp_list = current_retrievals;
2850 info = (GtkRetrievalInfo *)tmp_list->data;
2851 if (info->widget == widget)
2853 tmp_list = tmp_list->next;
2856 if (!tmp_list) /* No retrieval in progress */
2859 if (info->offset < 0) /* We haven't got the SelectionNotify
2860 for this retrieval yet */
2863 info->idle_time = 0;
2865 window = gtk_widget_get_window (widget);
2866 length = gdk_selection_property_get (window, &new_buffer,
2868 gdk_property_delete (window, event->atom);
2870 /* We could do a lot better efficiency-wise by paying attention to
2871 what length was sent in the initial INCR transaction, instead of
2872 doing memory allocation at every step. But its only guaranteed to
2873 be a _lower bound_ (pretty useless!) */
2875 if (length == 0 || type == GDK_NONE) /* final zero length portion */
2877 /* Info structure will be freed in timeout */
2878 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2879 g_list_free (tmp_list);
2880 gtk_selection_retrieval_report (info,
2882 (type == GDK_NONE) ? NULL : info->buffer,
2883 (type == GDK_NONE) ? -1 : info->offset,
2886 else /* append on newly arrived data */
2890 #ifdef DEBUG_SELECTION
2891 g_message ("Start - Adding %d bytes at offset 0",
2894 info->buffer = new_buffer;
2895 info->offset = length;
2900 #ifdef DEBUG_SELECTION
2901 g_message ("Appending %d bytes at offset %d",
2902 length,info->offset);
2904 /* We copy length+1 bytes to preserve guaranteed null termination */
2905 info->buffer = g_realloc (info->buffer, info->offset+length+1);
2906 memcpy (info->buffer + info->offset, new_buffer, length+1);
2907 info->offset += length;
2908 g_free (new_buffer);
2915 /*************************************************************
2916 * gtk_selection_retrieval_timeout:
2917 * Timeout callback while receiving a selection.
2919 * info: Information about this retrieval
2921 *************************************************************/
2924 gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
2929 /* Determine if retrieval has finished by checking if it still in
2930 list of pending retrievals */
2932 tmp_list = current_retrievals;
2935 if (info == (GtkRetrievalInfo *)tmp_list->data)
2937 tmp_list = tmp_list->next;
2940 /* If retrieval is finished */
2941 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2943 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2945 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2946 g_list_free (tmp_list);
2947 gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
2950 g_free (info->buffer);
2951 g_slice_free (GtkRetrievalInfo, info);
2953 retval = FALSE; /* remove timeout */
2959 retval = TRUE; /* timeout will happen again */
2965 /*************************************************************
2966 * gtk_selection_retrieval_report:
2967 * Emits a "selection-received" signal.
2969 * info: information about the retrieval that completed
2970 * buffer: buffer containing data (NULL => errror)
2971 * time: timestamp for data in buffer
2973 *************************************************************/
2976 gtk_selection_retrieval_report (GtkRetrievalInfo *info,
2977 GdkAtom type, gint format,
2978 guchar *buffer, gint length,
2981 GtkSelectionData data;
2983 data.selection = info->selection;
2984 data.target = info->target;
2986 data.format = format;
2988 data.length = length;
2990 data.display = gtk_widget_get_display (info->widget);
2992 g_signal_emit_by_name (info->widget,
2993 "selection-received",
2997 /*************************************************************
2998 * gtk_selection_invoke_handler:
2999 * Finds and invokes handler for specified
3000 * widget/selection/target combination, calls
3001 * gtk_selection_default_handler if none exists.
3004 * widget: selection owner
3005 * data: selection data [INOUT]
3006 * time: time from requeset
3009 * Number of bytes written to buffer, -1 if error
3010 *************************************************************/
3013 gtk_selection_invoke_handler (GtkWidget *widget,
3014 GtkSelectionData *data,
3017 GtkTargetList *target_list;
3021 g_return_if_fail (widget != NULL);
3023 target_list = gtk_selection_target_list_get (widget, data->selection);
3024 if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
3026 gtk_target_list_find (target_list, data->target, &info))
3028 g_signal_emit_by_name (widget,
3034 gtk_selection_default_handler (widget, data);
3037 /*************************************************************
3038 * gtk_selection_default_handler:
3039 * Handles some default targets that exist for any widget
3040 * If it can't fit results into buffer, returns -1. This
3041 * won't happen in any conceivable case, since it would
3042 * require 1000 selection targets!
3045 * widget: selection owner
3046 * data: selection data [INOUT]
3048 *************************************************************/
3051 gtk_selection_default_handler (GtkWidget *widget,
3052 GtkSelectionData *data)
3054 if (data->target == gtk_selection_atoms[TIMESTAMP])
3056 /* Time which was used to obtain selection */
3058 GtkSelectionInfo *selection_info;
3060 tmp_list = current_selections;
3063 selection_info = (GtkSelectionInfo *)tmp_list->data;
3064 if ((selection_info->widget == widget) &&
3065 (selection_info->selection == data->selection))
3067 gulong time = selection_info->time;
3069 gtk_selection_data_set (data,
3070 GDK_SELECTION_TYPE_INTEGER,
3077 tmp_list = tmp_list->next;
3082 else if (data->target == gtk_selection_atoms[TARGETS])
3084 /* List of all targets supported for this widget/selection pair */
3088 GtkTargetList *target_list;
3089 GtkTargetPair *pair;
3091 target_list = gtk_selection_target_list_get (widget,
3093 count = g_list_length (target_list->list) + 3;
3095 data->type = GDK_SELECTION_TYPE_ATOM;
3097 data->length = count * sizeof (GdkAtom);
3099 /* selection data is always terminated by a trailing \0
3101 p = g_malloc (data->length + 1);
3102 data->data = (guchar *)p;
3103 data->data[data->length] = '\0';
3105 *p++ = gtk_selection_atoms[TIMESTAMP];
3106 *p++ = gtk_selection_atoms[TARGETS];
3107 *p++ = gtk_selection_atoms[MULTIPLE];
3109 tmp_list = target_list->list;
3112 pair = (GtkTargetPair *)tmp_list->data;
3113 *p++ = pair->target;
3115 tmp_list = tmp_list->next;
3118 else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
3120 gtk_selection_data_set (data,
3121 gdk_atom_intern_static_string ("NULL"),
3132 * gtk_selection_data_copy:
3133 * @data: a pointer to a #GtkSelectionData structure.
3135 * Makes a copy of a #GtkSelectionData structure and its data.
3137 * Return value: a pointer to a copy of @data.
3140 gtk_selection_data_copy (const GtkSelectionData *data)
3142 GtkSelectionData *new_data;
3144 g_return_val_if_fail (data != NULL, NULL);
3146 new_data = g_slice_new (GtkSelectionData);
3151 new_data->data = g_malloc (data->length + 1);
3152 memcpy (new_data->data, data->data, data->length + 1);
3159 * gtk_selection_data_free:
3160 * @data: a pointer to a #GtkSelectionData structure.
3162 * Frees a #GtkSelectionData structure returned from
3163 * gtk_selection_data_copy().
3166 gtk_selection_data_free (GtkSelectionData *data)
3168 g_return_if_fail (data != NULL);
3170 g_free (data->data);
3172 g_slice_free (GtkSelectionData, data);
3176 * gtk_target_entry_new:
3177 * @target: String identifier for target
3178 * @flags: Set of flags, see #GtkTargetFlags
3179 * @info: an ID that will be passed back to the application
3181 * Makes a new #GtkTargetEntry structure.
3183 * Return value: a pointer to a new GtkTargetEntry structure.
3184 * Free with gtk_target_entry_free()
3187 gtk_target_entry_new (const char *target,
3191 GtkTargetEntry entry = { (char *) target, flags, info };
3192 return gtk_target_entry_copy (&entry);
3196 * gtk_target_entry_copy:
3197 * @data: a pointer to a #GtkTargetEntry structure.
3199 * Makes a copy of a #GtkTargetEntry structure and its data.
3201 * Return value: a pointer to a copy of @data.
3202 * Free with gtk_target_entry_free()
3205 gtk_target_entry_copy (GtkTargetEntry *data)
3207 GtkTargetEntry *new_data;
3209 g_return_val_if_fail (data != NULL, NULL);
3211 new_data = g_slice_new (GtkTargetEntry);
3212 new_data->target = g_strdup (data->target);
3213 new_data->flags = data->flags;
3214 new_data->info = data->info;
3220 * gtk_target_entry_free:
3221 * @data: a pointer to a #GtkTargetEntry structure.
3223 * Frees a #GtkTargetEntry structure returned from
3224 * gtk_target_entry_new() or gtk_target_entry_copy().
3227 gtk_target_entry_free (GtkTargetEntry *data)
3229 g_return_if_fail (data != NULL);
3231 g_free (data->target);
3233 g_slice_free (GtkTargetEntry, data);
3237 G_DEFINE_BOXED_TYPE (GtkSelectionData, gtk_selection_data,
3238 gtk_selection_data_copy,
3239 gtk_selection_data_free)
3241 G_DEFINE_BOXED_TYPE (GtkTargetList, gtk_target_list,
3242 gtk_target_list_ref,
3243 gtk_target_list_unref)
3245 G_DEFINE_BOXED_TYPE (GtkTargetEntry, gtk_target_entry,
3246 gtk_target_entry_copy,
3247 gtk_target_entry_free)
3250 gtk_selection_bytes_per_item (gint format)
3255 return sizeof (char);
3258 return sizeof (short);
3261 return sizeof (long);
3264 g_assert_not_reached();