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, see <http://www.gnu.org/licenses/>.
18 /* This file implements most of the work of the ICCCM selection protocol.
19 * The code was written after an intensive study of the equivalent part
20 * of John Ousterhout's Tk toolkit, and does many things in much the
23 * The one thing in the ICCCM that isn't fully supported here (or in Tk)
24 * is side effects targets. For these to be handled properly, MULTIPLE
25 * targets need to be done in the order specified. This cannot be
26 * guaranteed with the way we do things, since if we are doing INCR
27 * transfers, the order will depend on the timing of the requestor.
29 * By Owen Taylor <owt1@cornell.edu> 8/16/97
32 /* Terminology note: when not otherwise specified, the term "incr" below
33 * refers to the _sending_ part of the INCR protocol. The receiving
34 * portion is referred to just as "retrieval". (Terminology borrowed
35 * from Tk, because there is no good opposite to "retrieval" in English.
36 * "send" can't be made into a noun gracefully and we're already using
37 * "emission" for something else ....)
40 /* The MOTIF entry widget seems to ask for the TARGETS target, then
41 (regardless of the reply) ask for the TEXT target. It's slightly
42 possible though that it somehow thinks we are responding negatively
43 to the TARGETS request, though I don't really think so ... */
46 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
47 * file for a list of people on the GTK+ Team. See the ChangeLog
48 * files for a list of changes. These files are distributed with
49 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
53 * SECTION:gtkselection
55 * @Short_description: Functions for handling inter-process communication
57 * @See_also: #GtkWidget - Much of the operation of selections happens via
58 * signals for #GtkWidget. In particular, if you are using the functions
59 * in this section, you may need to pay attention to
60 * #GtkWidget::selection-get, #GtkWidget::selection-received and
61 * #GtkWidget::selection-clear-event signals
63 * The selection mechanism provides the basis for different types
64 * of communication between processes. In particular, drag and drop and
65 * #GtkClipboard work via selections. You will very seldom or
66 * never need to use most of the functions in this section directly;
67 * #GtkClipboard provides a nicer interface to the same functionality.
69 * Some of the datatypes defined this section are used in
70 * the #GtkClipboard and drag-and-drop API's as well. The
71 * #GtkTargetEntry structure and #GtkTargetList objects represent
72 * lists of data types that are supported when sending or
73 * receiving data. The #GtkSelectionData object is used to
74 * store a chunk of data along with the data type and other
75 * associated information.
80 #include "gtkselection.h"
81 #include "gtkselectionprivate.h"
89 #include "gtktextbufferrichtext.h"
91 #include "gdk-pixbuf/gdk-pixbuf.h"
93 #ifdef GDK_WINDOWING_X11
97 #ifdef GDK_WINDOWING_WIN32
98 #include "win32/gdkwin32.h"
101 #undef DEBUG_SELECTION
103 /* Maximum size of a sent chunk, in bytes. Also the default size of
105 #ifdef GDK_WINDOWING_X11
106 #define GTK_SELECTION_MAX_SIZE(display) \
108 XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
109 ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
110 : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
112 /* No chunks on Win32 */
113 #define GTK_SELECTION_MAX_SIZE(display) G_MAXINT
116 #define IDLE_ABORT_TIME 30
127 typedef struct _GtkSelectionInfo GtkSelectionInfo;
128 typedef struct _GtkIncrConversion GtkIncrConversion;
129 typedef struct _GtkIncrInfo GtkIncrInfo;
130 typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
132 struct _GtkSelectionInfo
135 GtkWidget *widget; /* widget that owns selection */
136 guint32 time; /* time used to acquire selection */
137 GdkDisplay *display; /* needed in gtk_selection_remove_all */
140 struct _GtkIncrConversion
142 GdkAtom target; /* Requested target */
143 GdkAtom property; /* Property to store in */
144 GtkSelectionData data; /* The data being supplied */
145 gint offset; /* Current offset in sent selection.
147 * -2 => Only the final (empty) portion
153 GdkWindow *requestor; /* Requestor window - we create a GdkWindow
154 so we can receive events */
155 GdkAtom selection; /* Selection we're sending */
157 GtkIncrConversion *conversions; /* Information about requested conversions -
158 * With MULTIPLE requests (benighted 1980's
159 * hardware idea), there can be more than
161 gint num_conversions;
162 gint num_incrs; /* number of remaining INCR style transactions */
167 struct _GtkRetrievalInfo
170 GdkAtom selection; /* Selection being retrieved. */
171 GdkAtom target; /* Form of selection that we requested */
172 guint32 idle_time; /* Number of seconds since we last heard
173 from selection owner */
174 guchar *buffer; /* Buffer in which to accumulate results */
175 gint offset; /* Current offset in buffer, -1 indicates
177 guint32 notify_time; /* Timestamp from SelectionNotify */
180 /* Local Functions */
181 static void gtk_selection_init (void);
182 static gboolean gtk_selection_incr_timeout (GtkIncrInfo *info);
183 static gboolean gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
184 static void gtk_selection_retrieval_report (GtkRetrievalInfo *info,
190 static void gtk_selection_invoke_handler (GtkWidget *widget,
191 GtkSelectionData *data,
193 static void gtk_selection_default_handler (GtkWidget *widget,
194 GtkSelectionData *data);
195 static int gtk_selection_bytes_per_item (gint format);
198 static gint initialize = TRUE;
199 static GList *current_retrievals = NULL;
200 static GList *current_incrs = NULL;
201 static GList *current_selections = NULL;
203 static GdkAtom gtk_selection_atoms[LAST_ATOM];
204 static const char gtk_selection_handler_key[] = "gtk-selection-handlers";
216 * gtk_target_list_new:
217 * @targets: (array length=ntargets): Pointer to an array of #GtkTargetEntry
218 * @ntargets: number of entries in @targets.
220 * Creates a new #GtkTargetList from an array of #GtkTargetEntry.
222 * Return value: (transfer full): the new #GtkTargetList.
225 gtk_target_list_new (const GtkTargetEntry *targets,
228 GtkTargetList *result = g_slice_new (GtkTargetList);
230 result->ref_count = 1;
233 gtk_target_list_add_table (result, targets, ntargets);
239 * gtk_target_list_ref:
240 * @list: a #GtkTargetList
242 * Increases the reference count of a #GtkTargetList by one.
244 * Return value: the passed in #GtkTargetList.
247 gtk_target_list_ref (GtkTargetList *list)
249 g_return_val_if_fail (list != NULL, NULL);
257 * gtk_target_list_unref:
258 * @list: a #GtkTargetList
260 * Decreases the reference count of a #GtkTargetList by one.
261 * If the resulting reference count is zero, frees the list.
264 gtk_target_list_unref (GtkTargetList *list)
266 g_return_if_fail (list != NULL);
267 g_return_if_fail (list->ref_count > 0);
270 if (list->ref_count == 0)
272 GList *tmp_list = list->list;
275 GtkTargetPair *pair = tmp_list->data;
276 g_slice_free (GtkTargetPair, pair);
278 tmp_list = tmp_list->next;
281 g_list_free (list->list);
282 g_slice_free (GtkTargetList, list);
287 * gtk_target_list_add:
288 * @list: a #GtkTargetList
289 * @target: the interned atom representing the target
290 * @flags: the flags for this target
291 * @info: an ID that will be passed back to the application
293 * Appends another target to a #GtkTargetList.
296 gtk_target_list_add (GtkTargetList *list,
303 g_return_if_fail (list != NULL);
305 pair = g_slice_new (GtkTargetPair);
306 pair->target = target;
310 list->list = g_list_append (list->list, pair);
313 static GdkAtom utf8_atom;
314 static GdkAtom text_atom;
315 static GdkAtom ctext_atom;
316 static GdkAtom text_plain_atom;
317 static GdkAtom text_plain_utf8_atom;
318 static GdkAtom text_plain_locale_atom;
319 static GdkAtom text_uri_list_atom;
325 const gchar *charset;
329 utf8_atom = gdk_atom_intern_static_string ("UTF8_STRING");
330 text_atom = gdk_atom_intern_static_string ("TEXT");
331 ctext_atom = gdk_atom_intern_static_string ("COMPOUND_TEXT");
332 text_plain_atom = gdk_atom_intern_static_string ("text/plain");
333 text_plain_utf8_atom = gdk_atom_intern_static_string ("text/plain;charset=utf-8");
334 g_get_charset (&charset);
335 tmp = g_strdup_printf ("text/plain;charset=%s", charset);
336 text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
339 text_uri_list_atom = gdk_atom_intern_static_string ("text/uri-list");
344 * gtk_target_list_add_text_targets:
345 * @list: a #GtkTargetList
346 * @info: an ID that will be passed back to the application
348 * Appends the text targets supported by #GtkSelection to
349 * the target list. All targets are added with the same @info.
354 gtk_target_list_add_text_targets (GtkTargetList *list,
357 g_return_if_fail (list != NULL);
361 /* Keep in sync with gtk_selection_data_targets_include_text()
363 gtk_target_list_add (list, utf8_atom, 0, info);
364 gtk_target_list_add (list, ctext_atom, 0, info);
365 gtk_target_list_add (list, text_atom, 0, info);
366 gtk_target_list_add (list, GDK_TARGET_STRING, 0, info);
367 gtk_target_list_add (list, text_plain_utf8_atom, 0, info);
368 if (!g_get_charset (NULL))
369 gtk_target_list_add (list, text_plain_locale_atom, 0, info);
370 gtk_target_list_add (list, text_plain_atom, 0, info);
374 * gtk_target_list_add_rich_text_targets:
375 * @list: a #GtkTargetList
376 * @info: an ID that will be passed back to the application
377 * @deserializable: if %TRUE, then deserializable rich text formats
378 * will be added, serializable formats otherwise.
379 * @buffer: a #GtkTextBuffer.
381 * Appends the rich text targets registered with
382 * gtk_text_buffer_register_serialize_format() or
383 * gtk_text_buffer_register_deserialize_format() to the target list. All
384 * targets are added with the same @info.
389 gtk_target_list_add_rich_text_targets (GtkTargetList *list,
391 gboolean deserializable,
392 GtkTextBuffer *buffer)
398 g_return_if_fail (list != NULL);
399 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
402 atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
404 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
406 for (i = 0; i < n_atoms; i++)
407 gtk_target_list_add (list, atoms[i], 0, info);
413 * gtk_target_list_add_image_targets:
414 * @list: a #GtkTargetList
415 * @info: an ID that will be passed back to the application
416 * @writable: whether to add only targets for which GTK+ knows
417 * how to convert a pixbuf into the format
419 * Appends the image targets supported by #GtkSelection to
420 * the target list. All targets are added with the same @info.
425 gtk_target_list_add_image_targets (GtkTargetList *list,
433 g_return_if_fail (list != NULL);
435 formats = gdk_pixbuf_get_formats ();
437 /* Make sure png comes first */
438 for (f = formats; f; f = f->next)
440 GdkPixbufFormat *fmt = f->data;
443 name = gdk_pixbuf_format_get_name (fmt);
444 if (strcmp (name, "png") == 0)
446 formats = g_slist_delete_link (formats, f);
447 formats = g_slist_prepend (formats, fmt);
457 for (f = formats; f; f = f->next)
459 GdkPixbufFormat *fmt = f->data;
461 if (writable && !gdk_pixbuf_format_is_writable (fmt))
464 mimes = gdk_pixbuf_format_get_mime_types (fmt);
465 for (m = mimes; *m; m++)
467 atom = gdk_atom_intern (*m, FALSE);
468 gtk_target_list_add (list, atom, 0, info);
473 g_slist_free (formats);
477 * gtk_target_list_add_uri_targets:
478 * @list: a #GtkTargetList
479 * @info: an ID that will be passed back to the application
481 * Appends the URI targets supported by #GtkSelection to
482 * the target list. All targets are added with the same @info.
487 gtk_target_list_add_uri_targets (GtkTargetList *list,
490 g_return_if_fail (list != NULL);
494 gtk_target_list_add (list, text_uri_list_atom, 0, info);
498 * gtk_target_list_add_table:
499 * @list: a #GtkTargetList
500 * @targets: (array length=ntargets): the table of #GtkTargetEntry
501 * @ntargets: number of targets in the table
503 * Prepends a table of #GtkTargetEntry to a target list.
506 gtk_target_list_add_table (GtkTargetList *list,
507 const GtkTargetEntry *targets,
512 for (i=ntargets-1; i >= 0; i--)
514 GtkTargetPair *pair = g_slice_new (GtkTargetPair);
515 pair->target = gdk_atom_intern (targets[i].target, FALSE);
516 pair->flags = targets[i].flags;
517 pair->info = targets[i].info;
519 list->list = g_list_prepend (list->list, pair);
524 * gtk_target_list_remove:
525 * @list: a #GtkTargetList
526 * @target: the interned atom representing the target
528 * Removes a target from a target list.
531 gtk_target_list_remove (GtkTargetList *list,
536 g_return_if_fail (list != NULL);
538 tmp_list = list->list;
541 GtkTargetPair *pair = tmp_list->data;
543 if (pair->target == target)
545 g_slice_free (GtkTargetPair, pair);
547 list->list = g_list_remove_link (list->list, tmp_list);
548 g_list_free_1 (tmp_list);
553 tmp_list = tmp_list->next;
558 * gtk_target_list_find:
559 * @list: a #GtkTargetList
560 * @target: an interned atom representing the target to search for
561 * @info: a pointer to the location to store application info for target,
564 * Looks up a given target in a #GtkTargetList.
566 * Return value: %TRUE if the target was found, otherwise %FALSE
569 gtk_target_list_find (GtkTargetList *list,
575 g_return_val_if_fail (list != NULL, FALSE);
577 tmp_list = list->list;
580 GtkTargetPair *pair = tmp_list->data;
582 if (pair->target == target)
590 tmp_list = tmp_list->next;
597 * gtk_target_table_new_from_list:
598 * @list: a #GtkTargetList
599 * @n_targets: (out): return location for the number ot targets in the table
601 * This function creates an #GtkTargetEntry array that contains the
602 * same targets as the passed %list. The returned table is newly
603 * allocated and should be freed using gtk_target_table_free() when no
606 * Return value: (array length=n_targets) (transfer full): the new table.
611 gtk_target_table_new_from_list (GtkTargetList *list,
614 GtkTargetEntry *targets;
618 g_return_val_if_fail (list != NULL, NULL);
619 g_return_val_if_fail (n_targets != NULL, NULL);
621 *n_targets = g_list_length (list->list);
622 targets = g_new0 (GtkTargetEntry, *n_targets);
624 for (i = 0, tmp_list = list->list;
626 i++, tmp_list = g_list_next (tmp_list))
628 GtkTargetPair *pair = tmp_list->data;
630 targets[i].target = gdk_atom_name (pair->target);
631 targets[i].flags = pair->flags;
632 targets[i].info = pair->info;
639 * gtk_target_table_free:
640 * @targets: (array length=n_targets): a #GtkTargetEntry array
641 * @n_targets: the number of entries in the array
643 * This function frees a target table as returned by
644 * gtk_target_table_new_from_list()
649 gtk_target_table_free (GtkTargetEntry *targets,
654 g_return_if_fail (targets == NULL || n_targets > 0);
656 for (i = 0; i < n_targets; i++)
657 g_free (targets[i].target);
663 * gtk_selection_owner_set_for_display:
664 * @display: the #GdkDisplay where the selection is set
665 * @widget: (allow-none): new selection owner (a #GtkWidget), or %NULL.
666 * @selection: an interned atom representing the selection to claim.
667 * @time_: timestamp with which to claim the selection
669 * Claim ownership of a given selection for a particular widget, or,
670 * if @widget is %NULL, release ownership of the selection.
672 * Return value: TRUE if the operation succeeded
677 gtk_selection_owner_set_for_display (GdkDisplay *display,
683 GtkWidget *old_owner;
684 GtkSelectionInfo *selection_info = NULL;
687 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
688 g_return_val_if_fail (selection != GDK_NONE, FALSE);
689 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
690 g_return_val_if_fail (widget == NULL || gtk_widget_get_display (widget) == display, FALSE);
695 window = gtk_widget_get_window (widget);
697 tmp_list = current_selections;
700 if (((GtkSelectionInfo *)tmp_list->data)->selection == selection)
702 selection_info = tmp_list->data;
706 tmp_list = tmp_list->next;
709 if (gdk_selection_owner_set_for_display (display, window, selection, time, TRUE))
717 old_owner = selection_info->widget;
718 current_selections = g_list_remove_link (current_selections,
720 g_list_free (tmp_list);
721 g_slice_free (GtkSelectionInfo, selection_info);
726 if (selection_info == NULL)
728 selection_info = g_slice_new (GtkSelectionInfo);
729 selection_info->selection = selection;
730 selection_info->widget = widget;
731 selection_info->time = time;
732 selection_info->display = display;
733 current_selections = g_list_prepend (current_selections,
738 old_owner = selection_info->widget;
739 selection_info->widget = widget;
740 selection_info->time = time;
741 selection_info->display = display;
744 /* If another widget in the application lost the selection,
745 * send it a GDK_SELECTION_CLEAR event.
747 if (old_owner && old_owner != widget)
749 GdkEvent *event = gdk_event_new (GDK_SELECTION_CLEAR);
751 event->selection.window = g_object_ref (gtk_widget_get_window (old_owner));
752 event->selection.selection = selection;
753 event->selection.time = time;
755 gtk_widget_event (old_owner, event);
757 gdk_event_free (event);
766 * gtk_selection_owner_set:
767 * @widget: (allow-none): a #GtkWidget, or %NULL.
768 * @selection: an interned atom representing the selection to claim
769 * @time_: timestamp with which to claim the selection
771 * Claims ownership of a given selection for a particular widget,
772 * or, if @widget is %NULL, release ownership of the selection.
774 * Return value: %TRUE if the operation succeeded
777 gtk_selection_owner_set (GtkWidget *widget,
783 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
784 g_return_val_if_fail (selection != GDK_NONE, FALSE);
787 display = gtk_widget_get_display (widget);
791 g_warning ("gtk_selection_owner_set (NULL,...) is not multihead safe"));
793 display = gdk_display_get_default ();
796 return gtk_selection_owner_set_for_display (display, widget,
800 typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
802 struct _GtkSelectionTargetList {
807 static GtkTargetList *
808 gtk_selection_target_list_get (GtkWidget *widget,
811 GtkSelectionTargetList *sellist;
815 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
820 sellist = tmp_list->data;
821 if (sellist->selection == selection)
822 return sellist->list;
823 tmp_list = tmp_list->next;
826 sellist = g_slice_new (GtkSelectionTargetList);
827 sellist->selection = selection;
828 sellist->list = gtk_target_list_new (NULL, 0);
830 lists = g_list_prepend (lists, sellist);
831 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
833 return sellist->list;
837 gtk_selection_target_list_remove (GtkWidget *widget)
839 GtkSelectionTargetList *sellist;
843 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
848 sellist = tmp_list->data;
850 gtk_target_list_unref (sellist->list);
852 g_slice_free (GtkSelectionTargetList, sellist);
853 tmp_list = tmp_list->next;
857 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), NULL);
861 * gtk_selection_clear_targets:
862 * @widget: a #GtkWidget
863 * @selection: an atom representing a selection
865 * Remove all targets registered for the given selection for the
869 gtk_selection_clear_targets (GtkWidget *widget,
872 GtkSelectionTargetList *sellist;
876 g_return_if_fail (GTK_IS_WIDGET (widget));
877 g_return_if_fail (selection != GDK_NONE);
879 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
884 sellist = tmp_list->data;
885 if (sellist->selection == selection)
887 lists = g_list_delete_link (lists, tmp_list);
888 gtk_target_list_unref (sellist->list);
889 g_slice_free (GtkSelectionTargetList, sellist);
894 tmp_list = tmp_list->next;
897 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
901 * gtk_selection_add_target:
902 * @widget: a #GtkTarget
903 * @selection: the selection
904 * @target: target to add.
905 * @info: A unsigned integer which will be passed back to the application.
907 * Appends a specified target to the list of supported targets for a
908 * given widget and selection.
911 gtk_selection_add_target (GtkWidget *widget,
918 g_return_if_fail (GTK_IS_WIDGET (widget));
919 g_return_if_fail (selection != GDK_NONE);
921 list = gtk_selection_target_list_get (widget, selection);
922 gtk_target_list_add (list, target, 0, info);
923 #ifdef GDK_WINDOWING_WIN32
924 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, 1, &target);
929 * gtk_selection_add_targets:
930 * @widget: a #GtkWidget
931 * @selection: the selection
932 * @targets: (array length=ntargets): a table of targets to add
933 * @ntargets: number of entries in @targets
935 * Prepends a table of targets to the list of supported targets
936 * for a given widget and selection.
939 gtk_selection_add_targets (GtkWidget *widget,
941 const GtkTargetEntry *targets,
946 g_return_if_fail (GTK_IS_WIDGET (widget));
947 g_return_if_fail (selection != GDK_NONE);
948 g_return_if_fail (targets != NULL);
950 list = gtk_selection_target_list_get (widget, selection);
951 gtk_target_list_add_table (list, targets, ntargets);
953 #ifdef GDK_WINDOWING_WIN32
956 GdkAtom *atoms = g_new (GdkAtom, ntargets);
958 for (i = 0; i < ntargets; ++i)
959 atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
960 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, ntargets, atoms);
968 * gtk_selection_remove_all:
969 * @widget: a #GtkWidget
971 * Removes all handlers and unsets ownership of all
972 * selections for a widget. Called when widget is being
973 * destroyed. This function will not generally be
974 * called by applications.
977 gtk_selection_remove_all (GtkWidget *widget)
981 GtkSelectionInfo *selection_info;
983 g_return_if_fail (GTK_IS_WIDGET (widget));
985 /* Remove pending requests/incrs for this widget */
987 tmp_list = current_retrievals;
990 next = tmp_list->next;
991 if (((GtkRetrievalInfo *)tmp_list->data)->widget == widget)
993 current_retrievals = g_list_remove_link (current_retrievals,
995 /* structure will be freed in timeout */
996 g_list_free (tmp_list);
1001 /* Disclaim ownership of any selections */
1003 tmp_list = current_selections;
1006 next = tmp_list->next;
1007 selection_info = (GtkSelectionInfo *)tmp_list->data;
1009 if (selection_info->widget == widget)
1011 gdk_selection_owner_set_for_display (selection_info->display,
1013 selection_info->selection,
1014 GDK_CURRENT_TIME, FALSE);
1015 current_selections = g_list_remove_link (current_selections,
1017 g_list_free (tmp_list);
1018 g_slice_free (GtkSelectionInfo, selection_info);
1024 /* Remove all selection lists */
1025 gtk_selection_target_list_remove (widget);
1030 * gtk_selection_convert:
1031 * @widget: The widget which acts as requestor
1032 * @selection: Which selection to get
1033 * @target: Form of information desired (e.g., STRING)
1034 * @time_: Time of request (usually of triggering event)
1035 In emergency, you could use #GDK_CURRENT_TIME
1037 * Requests the contents of a selection. When received,
1038 * a "selection-received" signal will be generated.
1040 * Return value: %TRUE if requested succeeded. %FALSE if we could not process
1041 * request. (e.g., there was already a request in process for
1045 gtk_selection_convert (GtkWidget *widget,
1050 GtkRetrievalInfo *info;
1052 GdkWindow *owner_window;
1053 GdkDisplay *display;
1055 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1056 g_return_val_if_fail (selection != GDK_NONE, FALSE);
1059 gtk_selection_init ();
1061 if (!gtk_widget_get_realized (widget))
1062 gtk_widget_realize (widget);
1064 /* Check to see if there are already any retrievals in progress for
1065 this widget. If we changed GDK to use the selection for the
1066 window property in which to store the retrieved information, then
1067 we could support multiple retrievals for different selections.
1068 This might be useful for DND. */
1070 tmp_list = current_retrievals;
1073 info = (GtkRetrievalInfo *)tmp_list->data;
1074 if (info->widget == widget)
1076 tmp_list = tmp_list->next;
1079 info = g_slice_new (GtkRetrievalInfo);
1081 info->widget = widget;
1082 info->selection = selection;
1083 info->target = target;
1084 info->idle_time = 0;
1085 info->buffer = NULL;
1088 /* Check if this process has current owner. If so, call handler
1089 procedure directly to avoid deadlocks with INCR. */
1091 display = gtk_widget_get_display (widget);
1092 owner_window = gdk_selection_owner_get_for_display (display, selection);
1094 if (owner_window != NULL)
1096 GtkWidget *owner_widget;
1097 gpointer owner_widget_ptr;
1098 GtkSelectionData selection_data = {0};
1100 selection_data.selection = selection;
1101 selection_data.target = target;
1102 selection_data.length = -1;
1103 selection_data.display = display;
1105 gdk_window_get_user_data (owner_window, &owner_widget_ptr);
1106 owner_widget = owner_widget_ptr;
1108 if (owner_widget != NULL)
1110 gtk_selection_invoke_handler (owner_widget,
1114 gtk_selection_retrieval_report (info,
1115 selection_data.type,
1116 selection_data.format,
1117 selection_data.data,
1118 selection_data.length,
1121 g_free (selection_data.data);
1122 selection_data.data = NULL;
1123 selection_data.length = -1;
1125 g_slice_free (GtkRetrievalInfo, info);
1130 /* Otherwise, we need to go through X */
1132 current_retrievals = g_list_append (current_retrievals, info);
1133 gdk_selection_convert (gtk_widget_get_window (widget), selection, target, time_);
1134 gdk_threads_add_timeout (1000,
1135 (GSourceFunc) gtk_selection_retrieval_timeout, info);
1141 * gtk_selection_data_get_selection:
1142 * @selection_data: a pointer to a #GtkSelectionData structure.
1144 * Retrieves the selection #GdkAtom of the selection data.
1146 * Returns: (transfer none): the selection #GdkAtom of the selection data.
1151 gtk_selection_data_get_selection (const GtkSelectionData *selection_data)
1153 g_return_val_if_fail (selection_data != NULL, 0);
1155 return selection_data->selection;
1159 * gtk_selection_data_get_target:
1160 * @selection_data: a pointer to a #GtkSelectionData structure.
1162 * Retrieves the target of the selection.
1164 * Returns: (transfer none): the target of the selection.
1169 gtk_selection_data_get_target (const GtkSelectionData *selection_data)
1171 g_return_val_if_fail (selection_data != NULL, 0);
1173 return selection_data->target;
1177 * gtk_selection_data_get_data_type:
1178 * @selection_data: a pointer to a #GtkSelectionData structure.
1180 * Retrieves the data type of the selection.
1182 * Returns: (transfer none): the data type of the selection.
1187 gtk_selection_data_get_data_type (const GtkSelectionData *selection_data)
1189 g_return_val_if_fail (selection_data != NULL, 0);
1191 return selection_data->type;
1195 * gtk_selection_data_get_format:
1196 * @selection_data: a pointer to a #GtkSelectionData structure.
1198 * Retrieves the format of the selection.
1200 * Returns: the format of the selection.
1205 gtk_selection_data_get_format (const GtkSelectionData *selection_data)
1207 g_return_val_if_fail (selection_data != NULL, 0);
1209 return selection_data->format;
1213 * gtk_selection_data_get_data: (skip)
1214 * @selection_data: a pointer to a #GtkSelectionData structure.
1216 * Retrieves the raw data of the selection.
1218 * Returns: the raw data of the selection.
1223 gtk_selection_data_get_data (const GtkSelectionData *selection_data)
1225 g_return_val_if_fail (selection_data != NULL, NULL);
1227 return selection_data->data;
1231 * gtk_selection_data_get_length:
1232 * @selection_data: a pointer to a #GtkSelectionData structure.
1234 * Retrieves the length of the raw data of the selection.
1236 * Returns: the length of the data of the selection.
1241 gtk_selection_data_get_length (const GtkSelectionData *selection_data)
1243 g_return_val_if_fail (selection_data != NULL, -1);
1245 return selection_data->length;
1249 * gtk_selection_data_get_data_with_length:
1250 * @selection_data: a pointer to a #GtkSelectionData structure
1251 * @length: (out): return location for length of the data segment
1253 * Retrieves the raw data of the selection along with its length.
1255 * Returns: (array length=length): the raw data of the selection
1257 * Rename to: gtk_selection_data_get_data
1261 gtk_selection_data_get_data_with_length (const GtkSelectionData *selection_data,
1264 g_return_val_if_fail (selection_data != NULL, NULL);
1266 *length = selection_data->length;
1268 return selection_data->data;
1272 * gtk_selection_data_get_display:
1273 * @selection_data: a pointer to a #GtkSelectionData structure.
1275 * Retrieves the display of the selection.
1277 * Returns: (transfer none): the display of the selection.
1282 gtk_selection_data_get_display (const GtkSelectionData *selection_data)
1284 g_return_val_if_fail (selection_data != NULL, NULL);
1286 return selection_data->display;
1290 * gtk_selection_data_set:
1291 * @selection_data: a pointer to a #GtkSelectionData structure.
1292 * @type: the type of selection data
1293 * @format: format (number of bits in a unit)
1294 * @data: (array length=length): pointer to the data (will be copied)
1295 * @length: length of the data
1297 * Stores new data into a #GtkSelectionData object. Should
1298 * <emphasis>only</emphasis> be called from a selection handler callback.
1299 * Zero-terminates the stored data.
1302 gtk_selection_data_set (GtkSelectionData *selection_data,
1308 g_return_if_fail (selection_data != NULL);
1310 g_free (selection_data->data);
1312 selection_data->type = type;
1313 selection_data->format = format;
1317 selection_data->data = g_new (guchar, length+1);
1318 memcpy (selection_data->data, data, length);
1319 selection_data->data[length] = 0;
1323 g_return_if_fail (length <= 0);
1326 selection_data->data = NULL;
1328 selection_data->data = (guchar *) g_strdup ("");
1331 selection_data->length = length;
1335 selection_set_string (GtkSelectionData *selection_data,
1339 gchar *tmp = g_strndup (str, len);
1340 gchar *latin1 = gdk_utf8_to_string_target (tmp);
1345 gtk_selection_data_set (selection_data,
1346 GDK_SELECTION_TYPE_STRING,
1347 8, (guchar *) latin1, strlen (latin1));
1357 selection_set_compound_text (GtkSelectionData *selection_data,
1366 gboolean result = FALSE;
1368 #ifdef GDK_WINDOWING_X11
1369 if (GDK_IS_X11_DISPLAY (selection_data->display))
1371 tmp = g_strndup (str, len);
1372 if (gdk_x11_display_utf8_to_compound_text (selection_data->display, tmp,
1373 &encoding, &format, &text, &new_length))
1375 gtk_selection_data_set (selection_data, encoding, format, text, new_length);
1376 gdk_x11_free_compound_text (text);
1387 /* Normalize \r and \n into \r\n
1390 normalize_to_crlf (const gchar *str,
1393 GString *result = g_string_sized_new (len);
1394 const gchar *p = str;
1395 const gchar *end = str + len;
1400 g_string_append_c (result, '\r');
1404 g_string_append_c (result, *p);
1406 if (p == end || *p != '\n')
1407 g_string_append_c (result, '\n');
1412 g_string_append_c (result, *p);
1416 return g_string_free (result, FALSE);
1419 /* Normalize \r and \r\n into \n
1422 normalize_to_lf (gchar *str,
1425 GString *result = g_string_sized_new (len);
1426 const gchar *p = str;
1434 g_string_append_c (result, '\n');
1440 g_string_append_c (result, *p);
1444 return g_string_free (result, FALSE);
1448 selection_set_text_plain (GtkSelectionData *selection_data,
1452 const gchar *charset = NULL;
1454 GError *error = NULL;
1456 result = normalize_to_crlf (str, len);
1457 if (selection_data->target == text_plain_atom)
1459 else if (selection_data->target == text_plain_locale_atom)
1460 g_get_charset (&charset);
1464 gchar *tmp = result;
1465 result = g_convert_with_fallback (tmp, -1,
1467 NULL, NULL, NULL, &error);
1473 g_warning ("Error converting from %s to %s: %s",
1474 "UTF-8", charset, error->message);
1475 g_error_free (error);
1480 gtk_selection_data_set (selection_data,
1481 selection_data->target,
1482 8, (guchar *) result, strlen (result));
1489 selection_get_text_plain (const GtkSelectionData *selection_data)
1491 const gchar *charset = NULL;
1492 gchar *str, *result;
1494 GError *error = NULL;
1496 str = g_strdup ((const gchar *) selection_data->data);
1497 len = selection_data->length;
1499 if (selection_data->type == text_plain_atom)
1500 charset = "ISO-8859-1";
1501 else if (selection_data->type == text_plain_locale_atom)
1502 g_get_charset (&charset);
1507 str = g_convert_with_fallback (tmp, len,
1509 NULL, NULL, &len, &error);
1514 g_warning ("Error converting from %s to %s: %s",
1515 charset, "UTF-8", error->message);
1516 g_error_free (error);
1521 else if (!g_utf8_validate (str, -1, NULL))
1523 g_warning ("Error converting from %s to %s: %s",
1524 "text/plain;charset=utf-8", "UTF-8", "invalid UTF-8");
1530 result = normalize_to_lf (str, len);
1533 return (guchar *) result;
1537 * gtk_selection_data_set_text:
1538 * @selection_data: a #GtkSelectionData
1539 * @str: a UTF-8 string
1540 * @len: the length of @str, or -1 if @str is nul-terminated.
1542 * Sets the contents of the selection from a UTF-8 encoded string.
1543 * The string is converted to the form determined by
1544 * @selection_data->target.
1546 * Return value: %TRUE if the selection was successfully set,
1550 gtk_selection_data_set_text (GtkSelectionData *selection_data,
1554 g_return_val_if_fail (selection_data != NULL, FALSE);
1561 if (selection_data->target == utf8_atom)
1563 gtk_selection_data_set (selection_data,
1565 8, (guchar *)str, len);
1568 else if (selection_data->target == GDK_TARGET_STRING)
1570 return selection_set_string (selection_data, str, len);
1572 else if (selection_data->target == ctext_atom ||
1573 selection_data->target == text_atom)
1575 if (selection_set_compound_text (selection_data, str, len))
1577 else if (selection_data->target == text_atom)
1578 return selection_set_string (selection_data, str, len);
1580 else if (selection_data->target == text_plain_atom ||
1581 selection_data->target == text_plain_utf8_atom ||
1582 selection_data->target == text_plain_locale_atom)
1584 return selection_set_text_plain (selection_data, str, len);
1591 * gtk_selection_data_get_text:
1592 * @selection_data: a #GtkSelectionData
1594 * Gets the contents of the selection data as a UTF-8 string.
1596 * Return value: (type utf8): if the selection data contained a
1597 * recognized text type and it could be converted to UTF-8, a newly
1598 * allocated string containing the converted text, otherwise %NULL.
1599 * If the result is non-%NULL it must be freed with g_free().
1602 gtk_selection_data_get_text (const GtkSelectionData *selection_data)
1604 guchar *result = NULL;
1606 g_return_val_if_fail (selection_data != NULL, NULL);
1610 if (selection_data->length >= 0 &&
1611 (selection_data->type == GDK_TARGET_STRING ||
1612 selection_data->type == ctext_atom ||
1613 selection_data->type == utf8_atom))
1617 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1618 selection_data->type,
1619 selection_data->format,
1620 selection_data->data,
1621 selection_data->length,
1624 result = (guchar *) list[0];
1626 for (i = 1; i < count; i++)
1630 else if (selection_data->length >= 0 &&
1631 (selection_data->type == text_plain_atom ||
1632 selection_data->type == text_plain_utf8_atom ||
1633 selection_data->type == text_plain_locale_atom))
1635 result = selection_get_text_plain (selection_data);
1642 * gtk_selection_data_set_pixbuf:
1643 * @selection_data: a #GtkSelectionData
1644 * @pixbuf: a #GdkPixbuf
1646 * Sets the contents of the selection from a #GdkPixbuf
1647 * The pixbuf is converted to the form determined by
1648 * @selection_data->target.
1650 * Return value: %TRUE if the selection was successfully set,
1656 gtk_selection_data_set_pixbuf (GtkSelectionData *selection_data,
1659 GSList *formats, *f;
1666 g_return_val_if_fail (selection_data != NULL, FALSE);
1667 g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE);
1669 formats = gdk_pixbuf_get_formats ();
1671 for (f = formats; f; f = f->next)
1673 GdkPixbufFormat *fmt = f->data;
1675 mimes = gdk_pixbuf_format_get_mime_types (fmt);
1676 for (m = mimes; *m; m++)
1678 atom = gdk_atom_intern (*m, FALSE);
1679 if (selection_data->target == atom)
1682 type = gdk_pixbuf_format_get_name (fmt);
1683 result = gdk_pixbuf_save_to_buffer (pixbuf, &str, &len,
1685 ((strcmp (type, "png") == 0) ?
1686 "compression" : NULL), "2",
1689 gtk_selection_data_set (selection_data,
1690 atom, 8, (guchar *)str, len);
1694 g_slist_free (formats);
1703 g_slist_free (formats);
1709 * gtk_selection_data_get_pixbuf:
1710 * @selection_data: a #GtkSelectionData
1712 * Gets the contents of the selection data as a #GdkPixbuf.
1714 * Return value: (transfer full): if the selection data contained a recognized
1715 * image type and it could be converted to a #GdkPixbuf, a
1716 * newly allocated pixbuf is returned, otherwise %NULL.
1717 * If the result is non-%NULL it must be freed with g_object_unref().
1722 gtk_selection_data_get_pixbuf (const GtkSelectionData *selection_data)
1724 GdkPixbufLoader *loader;
1725 GdkPixbuf *result = NULL;
1727 g_return_val_if_fail (selection_data != NULL, NULL);
1729 if (selection_data->length > 0)
1731 loader = gdk_pixbuf_loader_new ();
1733 gdk_pixbuf_loader_write (loader,
1734 selection_data->data,
1735 selection_data->length,
1737 gdk_pixbuf_loader_close (loader, NULL);
1738 result = gdk_pixbuf_loader_get_pixbuf (loader);
1741 g_object_ref (result);
1743 g_object_unref (loader);
1750 * gtk_selection_data_set_uris:
1751 * @selection_data: a #GtkSelectionData
1752 * @uris: (array zero-terminated=1): a %NULL-terminated array of
1753 * strings holding URIs
1755 * Sets the contents of the selection from a list of URIs.
1756 * The string is converted to the form determined by
1757 * @selection_data->target.
1759 * Return value: %TRUE if the selection was successfully set,
1765 gtk_selection_data_set_uris (GtkSelectionData *selection_data,
1768 g_return_val_if_fail (selection_data != NULL, FALSE);
1769 g_return_val_if_fail (uris != NULL, FALSE);
1773 if (selection_data->target == text_uri_list_atom)
1780 list = g_string_new (NULL);
1781 for (i = 0; uris[i]; i++)
1783 g_string_append (list, uris[i]);
1784 g_string_append (list, "\r\n");
1787 result = g_convert (list->str, list->len,
1789 NULL, &length, NULL);
1790 g_string_free (list, TRUE);
1794 gtk_selection_data_set (selection_data,
1796 8, (guchar *)result, length);
1808 * gtk_selection_data_get_uris:
1809 * @selection_data: a #GtkSelectionData
1811 * Gets the contents of the selection data as array of URIs.
1813 * Return value: (array zero-terminated=1) (element-type utf8) (transfer full): if
1814 * the selection data contains a list of
1815 * URIs, a newly allocated %NULL-terminated string array
1816 * containing the URIs, otherwise %NULL. If the result is
1817 * non-%NULL it must be freed with g_strfreev().
1822 gtk_selection_data_get_uris (const GtkSelectionData *selection_data)
1824 gchar **result = NULL;
1826 g_return_val_if_fail (selection_data != NULL, NULL);
1830 if (selection_data->length >= 0 &&
1831 selection_data->type == text_uri_list_atom)
1834 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1836 selection_data->format,
1837 selection_data->data,
1838 selection_data->length,
1841 result = g_uri_list_extract_uris (list[0]);
1851 * gtk_selection_data_get_targets:
1852 * @selection_data: a #GtkSelectionData object
1853 * @targets: (out) (array length=n_atoms) (transfer container):
1854 * location to store an array of targets. The result stored
1855 * here must be freed with g_free().
1856 * @n_atoms: location to store number of items in @targets.
1858 * Gets the contents of @selection_data as an array of targets.
1859 * This can be used to interpret the results of getting
1860 * the standard TARGETS target that is always supplied for
1863 * Return value: %TRUE if @selection_data contains a valid
1864 * array of targets, otherwise %FALSE.
1867 gtk_selection_data_get_targets (const GtkSelectionData *selection_data,
1871 g_return_val_if_fail (selection_data != NULL, FALSE);
1873 if (selection_data->length >= 0 &&
1874 selection_data->format == 32 &&
1875 selection_data->type == GDK_SELECTION_TYPE_ATOM)
1878 *targets = g_memdup (selection_data->data, selection_data->length);
1880 *n_atoms = selection_data->length / sizeof (GdkAtom);
1896 * gtk_targets_include_text:
1897 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1898 * @n_targets: the length of @targets
1900 * Determines if any of the targets in @targets can be used to
1903 * Return value: %TRUE if @targets include a suitable target for text,
1909 gtk_targets_include_text (GdkAtom *targets,
1913 gboolean result = FALSE;
1915 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1917 /* Keep in sync with gtk_target_list_add_text_targets()
1922 for (i = 0; i < n_targets; i++)
1924 if (targets[i] == utf8_atom ||
1925 targets[i] == text_atom ||
1926 targets[i] == GDK_TARGET_STRING ||
1927 targets[i] == ctext_atom ||
1928 targets[i] == text_plain_atom ||
1929 targets[i] == text_plain_utf8_atom ||
1930 targets[i] == text_plain_locale_atom)
1941 * gtk_targets_include_rich_text:
1942 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1943 * @n_targets: the length of @targets
1944 * @buffer: a #GtkTextBuffer
1946 * Determines if any of the targets in @targets can be used to
1947 * provide rich text.
1949 * Return value: %TRUE if @targets include a suitable target for rich text,
1955 gtk_targets_include_rich_text (GdkAtom *targets,
1957 GtkTextBuffer *buffer)
1959 GdkAtom *rich_targets;
1960 gint n_rich_targets;
1962 gboolean result = FALSE;
1964 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1965 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1969 rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
1972 for (i = 0; i < n_targets; i++)
1974 for (j = 0; j < n_rich_targets; j++)
1976 if (targets[i] == rich_targets[j])
1985 g_free (rich_targets);
1991 * gtk_selection_data_targets_include_text:
1992 * @selection_data: a #GtkSelectionData object
1994 * Given a #GtkSelectionData object holding a list of targets,
1995 * determines if any of the targets in @targets can be used to
1998 * Return value: %TRUE if @selection_data holds a list of targets,
1999 * and a suitable target for text is included, otherwise %FALSE.
2002 gtk_selection_data_targets_include_text (const GtkSelectionData *selection_data)
2006 gboolean result = FALSE;
2008 g_return_val_if_fail (selection_data != NULL, FALSE);
2012 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2014 result = gtk_targets_include_text (targets, n_targets);
2022 * gtk_selection_data_targets_include_rich_text:
2023 * @selection_data: a #GtkSelectionData object
2024 * @buffer: a #GtkTextBuffer
2026 * Given a #GtkSelectionData object holding a list of targets,
2027 * determines if any of the targets in @targets can be used to
2028 * provide rich text.
2030 * Return value: %TRUE if @selection_data holds a list of targets,
2031 * and a suitable target for rich text is included,
2037 gtk_selection_data_targets_include_rich_text (const GtkSelectionData *selection_data,
2038 GtkTextBuffer *buffer)
2042 gboolean result = FALSE;
2044 g_return_val_if_fail (selection_data != NULL, FALSE);
2045 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2049 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2051 result = gtk_targets_include_rich_text (targets, n_targets, buffer);
2059 * gtk_targets_include_image:
2060 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2061 * @n_targets: the length of @targets
2062 * @writable: whether to accept only targets for which GTK+ knows
2063 * how to convert a pixbuf into the format
2065 * Determines if any of the targets in @targets can be used to
2066 * provide a #GdkPixbuf.
2068 * Return value: %TRUE if @targets include a suitable target for images,
2074 gtk_targets_include_image (GdkAtom *targets,
2078 GtkTargetList *list;
2081 gboolean result = FALSE;
2083 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2085 list = gtk_target_list_new (NULL, 0);
2086 gtk_target_list_add_image_targets (list, 0, writable);
2087 for (i = 0; i < n_targets && !result; i++)
2089 for (l = list->list; l; l = l->next)
2091 GtkTargetPair *pair = (GtkTargetPair *)l->data;
2092 if (pair->target == targets[i])
2099 gtk_target_list_unref (list);
2105 * gtk_selection_data_targets_include_image:
2106 * @selection_data: a #GtkSelectionData object
2107 * @writable: whether to accept only targets for which GTK+ knows
2108 * how to convert a pixbuf into the format
2110 * Given a #GtkSelectionData object holding a list of targets,
2111 * determines if any of the targets in @targets can be used to
2112 * provide a #GdkPixbuf.
2114 * Return value: %TRUE if @selection_data holds a list of targets,
2115 * and a suitable target for images is included, otherwise %FALSE.
2120 gtk_selection_data_targets_include_image (const GtkSelectionData *selection_data,
2125 gboolean result = FALSE;
2127 g_return_val_if_fail (selection_data != NULL, FALSE);
2131 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2133 result = gtk_targets_include_image (targets, n_targets, writable);
2141 * gtk_targets_include_uri:
2142 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2143 * @n_targets: the length of @targets
2145 * Determines if any of the targets in @targets can be used to
2146 * provide an uri list.
2148 * Return value: %TRUE if @targets include a suitable target for uri lists,
2154 gtk_targets_include_uri (GdkAtom *targets,
2158 gboolean result = FALSE;
2160 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2162 /* Keep in sync with gtk_target_list_add_uri_targets()
2167 for (i = 0; i < n_targets; i++)
2169 if (targets[i] == text_uri_list_atom)
2180 * gtk_selection_data_targets_include_uri:
2181 * @selection_data: a #GtkSelectionData object
2183 * Given a #GtkSelectionData object holding a list of targets,
2184 * determines if any of the targets in @targets can be used to
2185 * provide a list or URIs.
2187 * Return value: %TRUE if @selection_data holds a list of targets,
2188 * and a suitable target for URI lists is included, otherwise %FALSE.
2193 gtk_selection_data_targets_include_uri (const GtkSelectionData *selection_data)
2197 gboolean result = FALSE;
2199 g_return_val_if_fail (selection_data != NULL, FALSE);
2203 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2205 result = gtk_targets_include_uri (targets, n_targets);
2213 /*************************************************************
2214 * gtk_selection_init:
2215 * Initialize local variables
2219 *************************************************************/
2222 gtk_selection_init (void)
2224 gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
2225 gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
2226 gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
2227 gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
2228 gtk_selection_atoms[SAVE_TARGETS] = gdk_atom_intern_static_string ("SAVE_TARGETS");
2234 * _gtk_selection_clear:
2235 * @widget: a #GtkWidget
2238 * The default handler for the #GtkWidget::selection-clear-event
2241 * Return value: %TRUE if the event was handled, otherwise false
2244 _gtk_selection_clear (GtkWidget *widget,
2245 GdkEventSelection *event)
2247 /* Note that we filter clear events in gdkselection-x11.c, so
2248 * that we only will get here if the clear event actually
2249 * represents a change that we didn't do ourself.
2252 GtkSelectionInfo *selection_info = NULL;
2254 tmp_list = current_selections;
2257 selection_info = (GtkSelectionInfo *)tmp_list->data;
2259 if ((selection_info->selection == event->selection) &&
2260 (selection_info->widget == widget))
2263 tmp_list = tmp_list->next;
2268 current_selections = g_list_remove_link (current_selections, tmp_list);
2269 g_list_free (tmp_list);
2270 g_slice_free (GtkSelectionInfo, selection_info);
2277 /*************************************************************
2278 * _gtk_selection_request:
2279 * Handler for "selection_request_event"
2284 *************************************************************/
2287 _gtk_selection_request (GtkWidget *widget,
2288 GdkEventSelection *event)
2290 GdkDisplay *display = gtk_widget_get_display (widget);
2294 gulong selection_max_size;
2297 gtk_selection_init ();
2299 selection_max_size = GTK_SELECTION_MAX_SIZE (display);
2301 /* Check if we own selection */
2303 tmp_list = current_selections;
2306 GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
2308 if ((selection_info->selection == event->selection) &&
2309 (selection_info->widget == widget))
2312 tmp_list = tmp_list->next;
2315 if (tmp_list == NULL)
2318 info = g_slice_new (GtkIncrInfo);
2320 g_object_ref (widget);
2322 info->selection = event->selection;
2323 info->num_incrs = 0;
2324 info->requestor = g_object_ref (event->requestor);
2326 /* Determine conversions we need to perform */
2327 if (event->target == gtk_selection_atoms[MULTIPLE])
2336 gdk_error_trap_push ();
2337 if (!gdk_property_get (info->requestor, event->property, GDK_NONE, /* AnyPropertyType */
2338 0, selection_max_size, FALSE,
2339 &type, &format, &length, &mult_atoms))
2341 gdk_selection_send_notify_for_display (display,
2347 g_free (mult_atoms);
2348 g_slice_free (GtkIncrInfo, info);
2349 gdk_error_trap_pop_ignored ();
2352 gdk_error_trap_pop_ignored ();
2354 /* This is annoying; the ICCCM doesn't specify the property type
2355 * used for the property contents, so the autoconversion for
2356 * ATOM / ATOM_PAIR in GDK doesn't work properly.
2358 #ifdef GDK_WINDOWING_X11
2359 if (type != GDK_SELECTION_TYPE_ATOM &&
2360 type != gdk_atom_intern_static_string ("ATOM_PAIR"))
2362 info->num_conversions = length / (2*sizeof (glong));
2363 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2365 for (i=0; i<info->num_conversions; i++)
2367 info->conversions[i].target = gdk_x11_xatom_to_atom_for_display (display,
2368 ((glong *)mult_atoms)[2*i]);
2369 info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
2370 ((glong *)mult_atoms)[2*i + 1]);
2373 g_free (mult_atoms);
2378 info->num_conversions = length / (2*sizeof (GdkAtom));
2379 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2381 for (i=0; i<info->num_conversions; i++)
2383 info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
2384 info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
2387 g_free (mult_atoms);
2390 else /* only a single conversion */
2392 info->conversions = g_new (GtkIncrConversion, 1);
2393 info->num_conversions = 1;
2394 info->conversions[0].target = event->target;
2395 info->conversions[0].property = event->property;
2398 /* Loop through conversions and determine which of these are big
2399 enough to require doing them via INCR */
2400 for (i=0; i<info->num_conversions; i++)
2402 GtkSelectionData data;
2405 data.selection = event->selection;
2406 data.target = info->conversions[i].target;
2409 data.display = gtk_widget_get_display (widget);
2411 #ifdef DEBUG_SELECTION
2412 g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
2414 info->conversions[i].target,
2415 gdk_atom_name (info->conversions[i].target),
2416 event->requestor, info->conversions[i].property);
2419 gtk_selection_invoke_handler (widget, &data, event->time);
2420 if (data.length < 0)
2422 info->conversions[i].property = GDK_NONE;
2426 g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE);
2428 items = data.length / gtk_selection_bytes_per_item (data.format);
2430 if (data.length > selection_max_size)
2432 /* Sending via INCR */
2433 #ifdef DEBUG_SELECTION
2434 g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n",
2435 data.length, selection_max_size);
2438 info->conversions[i].offset = 0;
2439 info->conversions[i].data = data;
2442 gdk_property_change (info->requestor,
2443 info->conversions[i].property,
2444 gtk_selection_atoms[INCR],
2446 GDK_PROP_MODE_REPLACE,
2447 (guchar *)&items, 1);
2451 info->conversions[i].offset = -1;
2453 gdk_property_change (info->requestor,
2454 info->conversions[i].property,
2457 GDK_PROP_MODE_REPLACE,
2464 /* If we have some INCR's, we need to send the rest of the data in
2467 if (info->num_incrs > 0)
2469 /* FIXME: this could be dangerous if window doesn't still
2472 #ifdef DEBUG_SELECTION
2473 g_message ("Starting INCR...");
2476 gdk_window_set_events (info->requestor,
2477 gdk_window_get_events (info->requestor) |
2478 GDK_PROPERTY_CHANGE_MASK);
2479 current_incrs = g_list_append (current_incrs, info);
2480 gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
2483 /* If it was a MULTIPLE request, set the property to indicate which
2484 conversions succeeded */
2485 if (event->target == gtk_selection_atoms[MULTIPLE])
2487 GdkAtom *mult_atoms = g_new (GdkAtom, 2 * info->num_conversions);
2488 for (i = 0; i < info->num_conversions; i++)
2490 mult_atoms[2*i] = info->conversions[i].target;
2491 mult_atoms[2*i+1] = info->conversions[i].property;
2494 gdk_property_change (info->requestor, event->property,
2495 gdk_atom_intern_static_string ("ATOM_PAIR"), 32,
2496 GDK_PROP_MODE_REPLACE,
2497 (guchar *)mult_atoms, 2*info->num_conversions);
2498 g_free (mult_atoms);
2501 if (info->num_conversions == 1 &&
2502 info->conversions[0].property == GDK_NONE)
2504 /* Reject the entire conversion */
2505 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2514 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2522 if (info->num_incrs == 0)
2524 g_free (info->conversions);
2525 g_slice_free (GtkIncrInfo, info);
2528 g_object_unref (widget);
2533 /*************************************************************
2534 * _gtk_selection_incr_event:
2535 * Called whenever an PropertyNotify event occurs for an
2536 * GdkWindow with user_data == NULL. These will be notifications
2537 * that a window we are sending the selection to via the
2538 * INCR protocol has deleted a property and is ready for
2542 * window: the requestor window
2543 * event: the property event structure
2546 *************************************************************/
2549 _gtk_selection_incr_event (GdkWindow *window,
2550 GdkEventProperty *event)
2553 GtkIncrInfo *info = NULL;
2556 gulong selection_max_size;
2560 if (event->state != GDK_PROPERTY_DELETE)
2563 #ifdef DEBUG_SELECTION
2564 g_message ("PropertyDelete, property %ld", event->atom);
2567 selection_max_size = GTK_SELECTION_MAX_SIZE (gdk_window_get_display (window));
2569 /* Now find the appropriate ongoing INCR */
2570 tmp_list = current_incrs;
2573 info = (GtkIncrInfo *)tmp_list->data;
2574 if (info->requestor == event->window)
2577 tmp_list = tmp_list->next;
2580 if (tmp_list == NULL)
2583 /* Find out which target this is for */
2584 for (i=0; i<info->num_conversions; i++)
2586 if (info->conversions[i].property == event->atom &&
2587 info->conversions[i].offset != -1)
2591 info->idle_time = 0;
2593 if (info->conversions[i].offset == -2) /* only the last 0-length
2601 num_bytes = info->conversions[i].data.length -
2602 info->conversions[i].offset;
2603 buffer = info->conversions[i].data.data +
2604 info->conversions[i].offset;
2606 if (num_bytes > selection_max_size)
2608 num_bytes = selection_max_size;
2609 info->conversions[i].offset += selection_max_size;
2612 info->conversions[i].offset = -2;
2614 #ifdef DEBUG_SELECTION
2615 g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",
2616 num_bytes, info->conversions[i].offset,
2617 GDK_WINDOW_XID(info->requestor), event->atom);
2620 bytes_per_item = gtk_selection_bytes_per_item (info->conversions[i].data.format);
2621 gdk_property_change (info->requestor, event->atom,
2622 info->conversions[i].data.type,
2623 info->conversions[i].data.format,
2624 GDK_PROP_MODE_REPLACE,
2626 num_bytes / bytes_per_item);
2628 if (info->conversions[i].offset == -2)
2630 g_free (info->conversions[i].data.data);
2631 info->conversions[i].data.data = NULL;
2637 info->conversions[i].offset = -1;
2642 /* Check if we're finished with all the targets */
2644 if (info->num_incrs == 0)
2646 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2647 g_list_free (tmp_list);
2648 /* Let the timeout free it */
2654 /*************************************************************
2655 * gtk_selection_incr_timeout:
2656 * Timeout callback for the sending portion of the INCR
2659 * info: Information about this incr
2661 *************************************************************/
2664 gtk_selection_incr_timeout (GtkIncrInfo *info)
2669 /* Determine if retrieval has finished by checking if it still in
2670 list of pending retrievals */
2672 tmp_list = current_incrs;
2675 if (info == (GtkIncrInfo *)tmp_list->data)
2677 tmp_list = tmp_list->next;
2680 /* If retrieval is finished */
2681 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2683 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2685 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2686 g_list_free (tmp_list);
2689 g_free (info->conversions);
2690 /* FIXME: we should check if requestor window is still in use,
2691 and if not, remove it? */
2693 g_slice_free (GtkIncrInfo, info);
2695 retval = FALSE; /* remove timeout */
2701 retval = TRUE; /* timeout will happen again */
2707 /*************************************************************
2708 * _gtk_selection_notify:
2709 * Handler for "selection-notify-event" signals on windows
2710 * where a retrieval is currently in process. The selection
2711 * owner has responded to our conversion request.
2713 * widget: Widget getting signal
2714 * event: Selection event structure
2715 * info: Information about this retrieval
2717 * was event handled?
2718 *************************************************************/
2721 _gtk_selection_notify (GtkWidget *widget,
2722 GdkEventSelection *event)
2725 GtkRetrievalInfo *info = NULL;
2727 guchar *buffer = NULL;
2732 #ifdef DEBUG_SELECTION
2733 g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",
2734 event->selection, event->target, event->property);
2737 window = gtk_widget_get_window (widget);
2739 tmp_list = current_retrievals;
2742 info = (GtkRetrievalInfo *)tmp_list->data;
2743 if (info->widget == widget && info->selection == event->selection)
2745 tmp_list = tmp_list->next;
2748 if (!tmp_list) /* no retrieval in progress */
2751 if (event->property != GDK_NONE)
2752 length = gdk_selection_property_get (window, &buffer,
2755 length = 0; /* silence gcc */
2757 if (event->property == GDK_NONE || buffer == NULL)
2759 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2760 g_list_free (tmp_list);
2761 /* structure will be freed in timeout */
2762 gtk_selection_retrieval_report (info,
2763 GDK_NONE, 0, NULL, -1, event->time);
2768 if (type == gtk_selection_atoms[INCR])
2770 /* The remainder of the selection will come through PropertyNotify
2773 info->notify_time = event->time;
2774 info->idle_time = 0;
2775 info->offset = 0; /* Mark as OK to proceed */
2776 gdk_window_set_events (window,
2777 gdk_window_get_events (window)
2778 | GDK_PROPERTY_CHANGE_MASK);
2782 /* We don't delete the info structure - that will happen in timeout */
2783 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2784 g_list_free (tmp_list);
2786 info->offset = length;
2787 gtk_selection_retrieval_report (info,
2789 buffer, length, event->time);
2792 gdk_property_delete (window, event->property);
2799 /*************************************************************
2800 * _gtk_selection_property_notify:
2801 * Handler for "property-notify-event" signals on windows
2802 * where a retrieval is currently in process. The selection
2803 * owner has added more data.
2805 * widget: Widget getting signal
2806 * event: Property event structure
2807 * info: Information about this retrieval
2809 * was event handled?
2810 *************************************************************/
2813 _gtk_selection_property_notify (GtkWidget *widget,
2814 GdkEventProperty *event)
2817 GtkRetrievalInfo *info = NULL;
2824 g_return_val_if_fail (widget != NULL, FALSE);
2825 g_return_val_if_fail (event != NULL, FALSE);
2827 #if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
2828 if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
2829 (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
2833 #ifdef DEBUG_SELECTION
2834 g_message ("PropertyNewValue, property %ld",
2838 tmp_list = current_retrievals;
2841 info = (GtkRetrievalInfo *)tmp_list->data;
2842 if (info->widget == widget)
2844 tmp_list = tmp_list->next;
2847 if (!tmp_list) /* No retrieval in progress */
2850 if (info->offset < 0) /* We haven't got the SelectionNotify
2851 for this retrieval yet */
2854 info->idle_time = 0;
2856 window = gtk_widget_get_window (widget);
2857 length = gdk_selection_property_get (window, &new_buffer,
2859 gdk_property_delete (window, event->atom);
2861 /* We could do a lot better efficiency-wise by paying attention to
2862 what length was sent in the initial INCR transaction, instead of
2863 doing memory allocation at every step. But its only guaranteed to
2864 be a _lower bound_ (pretty useless!) */
2866 if (length == 0 || type == GDK_NONE) /* final zero length portion */
2868 /* Info structure will be freed in timeout */
2869 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2870 g_list_free (tmp_list);
2871 gtk_selection_retrieval_report (info,
2873 (type == GDK_NONE) ? NULL : info->buffer,
2874 (type == GDK_NONE) ? -1 : info->offset,
2877 else /* append on newly arrived data */
2881 #ifdef DEBUG_SELECTION
2882 g_message ("Start - Adding %d bytes at offset 0",
2885 info->buffer = new_buffer;
2886 info->offset = length;
2891 #ifdef DEBUG_SELECTION
2892 g_message ("Appending %d bytes at offset %d",
2893 length,info->offset);
2895 /* We copy length+1 bytes to preserve guaranteed null termination */
2896 info->buffer = g_realloc (info->buffer, info->offset+length+1);
2897 memcpy (info->buffer + info->offset, new_buffer, length+1);
2898 info->offset += length;
2899 g_free (new_buffer);
2906 /*************************************************************
2907 * gtk_selection_retrieval_timeout:
2908 * Timeout callback while receiving a selection.
2910 * info: Information about this retrieval
2912 *************************************************************/
2915 gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
2920 /* Determine if retrieval has finished by checking if it still in
2921 list of pending retrievals */
2923 tmp_list = current_retrievals;
2926 if (info == (GtkRetrievalInfo *)tmp_list->data)
2928 tmp_list = tmp_list->next;
2931 /* If retrieval is finished */
2932 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2934 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2936 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2937 g_list_free (tmp_list);
2938 gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
2941 g_free (info->buffer);
2942 g_slice_free (GtkRetrievalInfo, info);
2944 retval = FALSE; /* remove timeout */
2950 retval = TRUE; /* timeout will happen again */
2956 /*************************************************************
2957 * gtk_selection_retrieval_report:
2958 * Emits a "selection-received" signal.
2960 * info: information about the retrieval that completed
2961 * buffer: buffer containing data (NULL => errror)
2962 * time: timestamp for data in buffer
2964 *************************************************************/
2967 gtk_selection_retrieval_report (GtkRetrievalInfo *info,
2968 GdkAtom type, gint format,
2969 guchar *buffer, gint length,
2972 GtkSelectionData data;
2974 data.selection = info->selection;
2975 data.target = info->target;
2977 data.format = format;
2979 data.length = length;
2981 data.display = gtk_widget_get_display (info->widget);
2983 g_signal_emit_by_name (info->widget,
2984 "selection-received",
2988 /*************************************************************
2989 * gtk_selection_invoke_handler:
2990 * Finds and invokes handler for specified
2991 * widget/selection/target combination, calls
2992 * gtk_selection_default_handler if none exists.
2995 * widget: selection owner
2996 * data: selection data [INOUT]
2997 * time: time from requeset
3000 * Number of bytes written to buffer, -1 if error
3001 *************************************************************/
3004 gtk_selection_invoke_handler (GtkWidget *widget,
3005 GtkSelectionData *data,
3008 GtkTargetList *target_list;
3012 g_return_if_fail (widget != NULL);
3014 target_list = gtk_selection_target_list_get (widget, data->selection);
3015 if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
3017 gtk_target_list_find (target_list, data->target, &info))
3019 g_signal_emit_by_name (widget,
3025 gtk_selection_default_handler (widget, data);
3028 /*************************************************************
3029 * gtk_selection_default_handler:
3030 * Handles some default targets that exist for any widget
3031 * If it can't fit results into buffer, returns -1. This
3032 * won't happen in any conceivable case, since it would
3033 * require 1000 selection targets!
3036 * widget: selection owner
3037 * data: selection data [INOUT]
3039 *************************************************************/
3042 gtk_selection_default_handler (GtkWidget *widget,
3043 GtkSelectionData *data)
3045 if (data->target == gtk_selection_atoms[TIMESTAMP])
3047 /* Time which was used to obtain selection */
3049 GtkSelectionInfo *selection_info;
3051 tmp_list = current_selections;
3054 selection_info = (GtkSelectionInfo *)tmp_list->data;
3055 if ((selection_info->widget == widget) &&
3056 (selection_info->selection == data->selection))
3058 gulong time = selection_info->time;
3060 gtk_selection_data_set (data,
3061 GDK_SELECTION_TYPE_INTEGER,
3068 tmp_list = tmp_list->next;
3073 else if (data->target == gtk_selection_atoms[TARGETS])
3075 /* List of all targets supported for this widget/selection pair */
3079 GtkTargetList *target_list;
3080 GtkTargetPair *pair;
3082 target_list = gtk_selection_target_list_get (widget,
3084 count = g_list_length (target_list->list) + 3;
3086 data->type = GDK_SELECTION_TYPE_ATOM;
3088 data->length = count * sizeof (GdkAtom);
3090 /* selection data is always terminated by a trailing \0
3092 p = g_malloc (data->length + 1);
3093 data->data = (guchar *)p;
3094 data->data[data->length] = '\0';
3096 *p++ = gtk_selection_atoms[TIMESTAMP];
3097 *p++ = gtk_selection_atoms[TARGETS];
3098 *p++ = gtk_selection_atoms[MULTIPLE];
3100 tmp_list = target_list->list;
3103 pair = (GtkTargetPair *)tmp_list->data;
3104 *p++ = pair->target;
3106 tmp_list = tmp_list->next;
3109 else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
3111 gtk_selection_data_set (data,
3112 gdk_atom_intern_static_string ("NULL"),
3123 * gtk_selection_data_copy:
3124 * @data: a pointer to a #GtkSelectionData structure.
3126 * Makes a copy of a #GtkSelectionData structure and its data.
3128 * Return value: a pointer to a copy of @data.
3131 gtk_selection_data_copy (const GtkSelectionData *data)
3133 GtkSelectionData *new_data;
3135 g_return_val_if_fail (data != NULL, NULL);
3137 new_data = g_slice_new (GtkSelectionData);
3142 new_data->data = g_malloc (data->length + 1);
3143 memcpy (new_data->data, data->data, data->length + 1);
3150 * gtk_selection_data_free:
3151 * @data: a pointer to a #GtkSelectionData structure.
3153 * Frees a #GtkSelectionData structure returned from
3154 * gtk_selection_data_copy().
3157 gtk_selection_data_free (GtkSelectionData *data)
3159 g_return_if_fail (data != NULL);
3161 g_free (data->data);
3163 g_slice_free (GtkSelectionData, data);
3167 * gtk_target_entry_new:
3168 * @target: String identifier for target
3169 * @flags: Set of flags, see #GtkTargetFlags
3170 * @info: an ID that will be passed back to the application
3172 * Makes a new #GtkTargetEntry structure.
3174 * Return value: a pointer to a new GtkTargetEntry structure.
3175 * Free with gtk_target_entry_free()
3178 gtk_target_entry_new (const char *target,
3182 GtkTargetEntry entry = { (char *) target, flags, info };
3183 return gtk_target_entry_copy (&entry);
3187 * gtk_target_entry_copy:
3188 * @data: a pointer to a #GtkTargetEntry structure.
3190 * Makes a copy of a #GtkTargetEntry structure and its data.
3192 * Return value: a pointer to a copy of @data.
3193 * Free with gtk_target_entry_free()
3196 gtk_target_entry_copy (GtkTargetEntry *data)
3198 GtkTargetEntry *new_data;
3200 g_return_val_if_fail (data != NULL, NULL);
3202 new_data = g_slice_new (GtkTargetEntry);
3203 new_data->target = g_strdup (data->target);
3204 new_data->flags = data->flags;
3205 new_data->info = data->info;
3211 * gtk_target_entry_free:
3212 * @data: a pointer to a #GtkTargetEntry structure.
3214 * Frees a #GtkTargetEntry structure returned from
3215 * gtk_target_entry_new() or gtk_target_entry_copy().
3218 gtk_target_entry_free (GtkTargetEntry *data)
3220 g_return_if_fail (data != NULL);
3222 g_free (data->target);
3224 g_slice_free (GtkTargetEntry, data);
3228 G_DEFINE_BOXED_TYPE (GtkSelectionData, gtk_selection_data,
3229 gtk_selection_data_copy,
3230 gtk_selection_data_free)
3232 G_DEFINE_BOXED_TYPE (GtkTargetList, gtk_target_list,
3233 gtk_target_list_ref,
3234 gtk_target_list_unref)
3236 G_DEFINE_BOXED_TYPE (GtkTargetEntry, gtk_target_entry,
3237 gtk_target_entry_copy,
3238 gtk_target_entry_free)
3241 gtk_selection_bytes_per_item (gint format)
3246 return sizeof (char);
3249 return sizeof (short);
3252 return sizeof (long);
3255 g_assert_not_reached();