1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 /* This file implements most of the work of the ICCCM selection protocol.
21 * The code was written after an intensive study of the equivalent part
22 * of John Ousterhout's Tk toolkit, and does many things in much the
25 * The one thing in the ICCCM that isn't fully supported here (or in Tk)
26 * is side effects targets. For these to be handled properly, MULTIPLE
27 * targets need to be done in the order specified. This cannot be
28 * guaranteed with the way we do things, since if we are doing INCR
29 * transfers, the order will depend on the timing of the requestor.
31 * By Owen Taylor <owt1@cornell.edu> 8/16/97
34 /* Terminology note: when not otherwise specified, the term "incr" below
35 * refers to the _sending_ part of the INCR protocol. The receiving
36 * portion is referred to just as "retrieval". (Terminology borrowed
37 * from Tk, because there is no good opposite to "retrieval" in English.
38 * "send" can't be made into a noun gracefully and we're already using
39 * "emission" for something else ....)
42 /* The MOTIF entry widget seems to ask for the TARGETS target, then
43 (regardless of the reply) ask for the TEXT target. It's slightly
44 possible though that it somehow thinks we are responding negatively
45 to the TARGETS request, though I don't really think so ... */
48 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
49 * file for a list of people on the GTK+ Team. See the ChangeLog
50 * files for a list of changes. These files are distributed with
51 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
55 * SECTION:gtkselection
57 * @Short_description: Functions for handling inter-process communication
59 * @See_also: #GtkWidget - Much of the operation of selections happens via
60 * signals for #GtkWidget. In particular, if you are using the functions
61 * in this section, you may need to pay attention to
62 * #GtkWidget::selection-get, #GtkWidget::selection-received and
63 * #GtkWidget::selection-clear-event signals
65 * The selection mechanism provides the basis for different types
66 * of communication between processes. In particular, drag and drop and
67 * #GtkClipboard work via selections. You will very seldom or
68 * never need to use most of the functions in this section directly;
69 * #GtkClipboard provides a nicer interface to the same functionality.
71 * Some of the datatypes defined this section are used in
72 * the #GtkClipboard and drag-and-drop API's as well. The
73 * #GtkTargetEntry structure and #GtkTargetList objects represent
74 * lists of data types that are supported when sending or
75 * receiving data. The #GtkSelectionData object is used to
76 * store a chunk of data along with the data type and other
77 * associated information.
82 #include "gtkselection.h"
83 #include "gtkselectionprivate.h"
91 #include "gtktextbufferrichtext.h"
93 #include "gdk-pixbuf/gdk-pixbuf.h"
95 #ifdef GDK_WINDOWING_X11
99 #ifdef GDK_WINDOWING_WIN32
100 #include "win32/gdkwin32.h"
103 #undef DEBUG_SELECTION
105 /* Maximum size of a sent chunk, in bytes. Also the default size of
107 #ifdef GDK_WINDOWING_X11
108 #define GTK_SELECTION_MAX_SIZE(display) \
110 XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
111 ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
112 : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
114 /* No chunks on Win32 */
115 #define GTK_SELECTION_MAX_SIZE(display) G_MAXINT
118 #define IDLE_ABORT_TIME 30
129 typedef struct _GtkSelectionInfo GtkSelectionInfo;
130 typedef struct _GtkIncrConversion GtkIncrConversion;
131 typedef struct _GtkIncrInfo GtkIncrInfo;
132 typedef struct _GtkRetrievalInfo GtkRetrievalInfo;
134 struct _GtkSelectionInfo
137 GtkWidget *widget; /* widget that owns selection */
138 guint32 time; /* time used to acquire selection */
139 GdkDisplay *display; /* needed in gtk_selection_remove_all */
142 struct _GtkIncrConversion
144 GdkAtom target; /* Requested target */
145 GdkAtom property; /* Property to store in */
146 GtkSelectionData data; /* The data being supplied */
147 gint offset; /* Current offset in sent selection.
149 * -2 => Only the final (empty) portion
155 GdkWindow *requestor; /* Requestor window - we create a GdkWindow
156 so we can receive events */
157 GdkAtom selection; /* Selection we're sending */
159 GtkIncrConversion *conversions; /* Information about requested conversions -
160 * With MULTIPLE requests (benighted 1980's
161 * hardware idea), there can be more than
163 gint num_conversions;
164 gint num_incrs; /* number of remaining INCR style transactions */
169 struct _GtkRetrievalInfo
172 GdkAtom selection; /* Selection being retrieved. */
173 GdkAtom target; /* Form of selection that we requested */
174 guint32 idle_time; /* Number of seconds since we last heard
175 from selection owner */
176 guchar *buffer; /* Buffer in which to accumulate results */
177 gint offset; /* Current offset in buffer, -1 indicates
179 guint32 notify_time; /* Timestamp from SelectionNotify */
182 /* Local Functions */
183 static void gtk_selection_init (void);
184 static gboolean gtk_selection_incr_timeout (GtkIncrInfo *info);
185 static gboolean gtk_selection_retrieval_timeout (GtkRetrievalInfo *info);
186 static void gtk_selection_retrieval_report (GtkRetrievalInfo *info,
192 static void gtk_selection_invoke_handler (GtkWidget *widget,
193 GtkSelectionData *data,
195 static void gtk_selection_default_handler (GtkWidget *widget,
196 GtkSelectionData *data);
197 static int gtk_selection_bytes_per_item (gint format);
200 static gint initialize = TRUE;
201 static GList *current_retrievals = NULL;
202 static GList *current_incrs = NULL;
203 static GList *current_selections = NULL;
205 static GdkAtom gtk_selection_atoms[LAST_ATOM];
206 static const char gtk_selection_handler_key[] = "gtk-selection-handlers";
218 * gtk_target_list_new:
219 * @targets: (array length=ntargets): Pointer to an array of #GtkTargetEntry
220 * @ntargets: number of entries in @targets.
222 * Creates a new #GtkTargetList from an array of #GtkTargetEntry.
224 * Return value: (transfer full): the new #GtkTargetList.
227 gtk_target_list_new (const GtkTargetEntry *targets,
230 GtkTargetList *result = g_slice_new (GtkTargetList);
232 result->ref_count = 1;
235 gtk_target_list_add_table (result, targets, ntargets);
241 * gtk_target_list_ref:
242 * @list: a #GtkTargetList
244 * Increases the reference count of a #GtkTargetList by one.
246 * Return value: the passed in #GtkTargetList.
249 gtk_target_list_ref (GtkTargetList *list)
251 g_return_val_if_fail (list != NULL, NULL);
259 * gtk_target_list_unref:
260 * @list: a #GtkTargetList
262 * Decreases the reference count of a #GtkTargetList by one.
263 * If the resulting reference count is zero, frees the list.
266 gtk_target_list_unref (GtkTargetList *list)
268 g_return_if_fail (list != NULL);
269 g_return_if_fail (list->ref_count > 0);
272 if (list->ref_count == 0)
274 GList *tmp_list = list->list;
277 GtkTargetPair *pair = tmp_list->data;
278 g_slice_free (GtkTargetPair, pair);
280 tmp_list = tmp_list->next;
283 g_list_free (list->list);
284 g_slice_free (GtkTargetList, list);
289 * gtk_target_list_add:
290 * @list: a #GtkTargetList
291 * @target: the interned atom representing the target
292 * @flags: the flags for this target
293 * @info: an ID that will be passed back to the application
295 * Appends another target to a #GtkTargetList.
298 gtk_target_list_add (GtkTargetList *list,
305 g_return_if_fail (list != NULL);
307 pair = g_slice_new (GtkTargetPair);
308 pair->target = target;
312 list->list = g_list_append (list->list, pair);
315 static GdkAtom utf8_atom;
316 static GdkAtom text_atom;
317 static GdkAtom ctext_atom;
318 static GdkAtom text_plain_atom;
319 static GdkAtom text_plain_utf8_atom;
320 static GdkAtom text_plain_locale_atom;
321 static GdkAtom text_uri_list_atom;
327 const gchar *charset;
331 utf8_atom = gdk_atom_intern_static_string ("UTF8_STRING");
332 text_atom = gdk_atom_intern_static_string ("TEXT");
333 ctext_atom = gdk_atom_intern_static_string ("COMPOUND_TEXT");
334 text_plain_atom = gdk_atom_intern_static_string ("text/plain");
335 text_plain_utf8_atom = gdk_atom_intern_static_string ("text/plain;charset=utf-8");
336 g_get_charset (&charset);
337 tmp = g_strdup_printf ("text/plain;charset=%s", charset);
338 text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
341 text_uri_list_atom = gdk_atom_intern_static_string ("text/uri-list");
346 * gtk_target_list_add_text_targets:
347 * @list: a #GtkTargetList
348 * @info: an ID that will be passed back to the application
350 * Appends the text targets supported by #GtkSelection to
351 * the target list. All targets are added with the same @info.
356 gtk_target_list_add_text_targets (GtkTargetList *list,
359 g_return_if_fail (list != NULL);
363 /* Keep in sync with gtk_selection_data_targets_include_text()
365 gtk_target_list_add (list, utf8_atom, 0, info);
366 gtk_target_list_add (list, ctext_atom, 0, info);
367 gtk_target_list_add (list, text_atom, 0, info);
368 gtk_target_list_add (list, GDK_TARGET_STRING, 0, info);
369 gtk_target_list_add (list, text_plain_utf8_atom, 0, info);
370 if (!g_get_charset (NULL))
371 gtk_target_list_add (list, text_plain_locale_atom, 0, info);
372 gtk_target_list_add (list, text_plain_atom, 0, info);
376 * gtk_target_list_add_rich_text_targets:
377 * @list: a #GtkTargetList
378 * @info: an ID that will be passed back to the application
379 * @deserializable: if %TRUE, then deserializable rich text formats
380 * will be added, serializable formats otherwise.
381 * @buffer: a #GtkTextBuffer.
383 * Appends the rich text targets registered with
384 * gtk_text_buffer_register_serialize_format() or
385 * gtk_text_buffer_register_deserialize_format() to the target list. All
386 * targets are added with the same @info.
391 gtk_target_list_add_rich_text_targets (GtkTargetList *list,
393 gboolean deserializable,
394 GtkTextBuffer *buffer)
400 g_return_if_fail (list != NULL);
401 g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
404 atoms = gtk_text_buffer_get_deserialize_formats (buffer, &n_atoms);
406 atoms = gtk_text_buffer_get_serialize_formats (buffer, &n_atoms);
408 for (i = 0; i < n_atoms; i++)
409 gtk_target_list_add (list, atoms[i], 0, info);
415 * gtk_target_list_add_image_targets:
416 * @list: a #GtkTargetList
417 * @info: an ID that will be passed back to the application
418 * @writable: whether to add only targets for which GTK+ knows
419 * how to convert a pixbuf into the format
421 * Appends the image targets supported by #GtkSelection to
422 * the target list. All targets are added with the same @info.
427 gtk_target_list_add_image_targets (GtkTargetList *list,
435 g_return_if_fail (list != NULL);
437 formats = gdk_pixbuf_get_formats ();
439 /* Make sure png comes first */
440 for (f = formats; f; f = f->next)
442 GdkPixbufFormat *fmt = f->data;
445 name = gdk_pixbuf_format_get_name (fmt);
446 if (strcmp (name, "png") == 0)
448 formats = g_slist_delete_link (formats, f);
449 formats = g_slist_prepend (formats, fmt);
459 for (f = formats; f; f = f->next)
461 GdkPixbufFormat *fmt = f->data;
463 if (writable && !gdk_pixbuf_format_is_writable (fmt))
466 mimes = gdk_pixbuf_format_get_mime_types (fmt);
467 for (m = mimes; *m; m++)
469 atom = gdk_atom_intern (*m, FALSE);
470 gtk_target_list_add (list, atom, 0, info);
475 g_slist_free (formats);
479 * gtk_target_list_add_uri_targets:
480 * @list: a #GtkTargetList
481 * @info: an ID that will be passed back to the application
483 * Appends the URI targets supported by #GtkSelection to
484 * the target list. All targets are added with the same @info.
489 gtk_target_list_add_uri_targets (GtkTargetList *list,
492 g_return_if_fail (list != NULL);
496 gtk_target_list_add (list, text_uri_list_atom, 0, info);
500 * gtk_target_list_add_table:
501 * @list: a #GtkTargetList
502 * @targets: (array length=ntargets): the table of #GtkTargetEntry
503 * @ntargets: number of targets in the table
505 * Prepends a table of #GtkTargetEntry to a target list.
508 gtk_target_list_add_table (GtkTargetList *list,
509 const GtkTargetEntry *targets,
514 for (i=ntargets-1; i >= 0; i--)
516 GtkTargetPair *pair = g_slice_new (GtkTargetPair);
517 pair->target = gdk_atom_intern (targets[i].target, FALSE);
518 pair->flags = targets[i].flags;
519 pair->info = targets[i].info;
521 list->list = g_list_prepend (list->list, pair);
526 * gtk_target_list_remove:
527 * @list: a #GtkTargetList
528 * @target: the interned atom representing the target
530 * Removes a target from a target list.
533 gtk_target_list_remove (GtkTargetList *list,
538 g_return_if_fail (list != NULL);
540 tmp_list = list->list;
543 GtkTargetPair *pair = tmp_list->data;
545 if (pair->target == target)
547 g_slice_free (GtkTargetPair, pair);
549 list->list = g_list_remove_link (list->list, tmp_list);
550 g_list_free_1 (tmp_list);
555 tmp_list = tmp_list->next;
560 * gtk_target_list_find:
561 * @list: a #GtkTargetList
562 * @target: an interned atom representing the target to search for
563 * @info: a pointer to the location to store application info for target,
566 * Looks up a given target in a #GtkTargetList.
568 * Return value: %TRUE if the target was found, otherwise %FALSE
571 gtk_target_list_find (GtkTargetList *list,
577 g_return_val_if_fail (list != NULL, FALSE);
579 tmp_list = list->list;
582 GtkTargetPair *pair = tmp_list->data;
584 if (pair->target == target)
592 tmp_list = tmp_list->next;
599 * gtk_target_table_new_from_list:
600 * @list: a #GtkTargetList
601 * @n_targets: (out): return location for the number ot targets in the table
603 * This function creates an #GtkTargetEntry array that contains the
604 * same targets as the passed %list. The returned table is newly
605 * allocated and should be freed using gtk_target_table_free() when no
608 * Return value: (array length=n_targets) (transfer full): the new table.
613 gtk_target_table_new_from_list (GtkTargetList *list,
616 GtkTargetEntry *targets;
620 g_return_val_if_fail (list != NULL, NULL);
621 g_return_val_if_fail (n_targets != NULL, NULL);
623 *n_targets = g_list_length (list->list);
624 targets = g_new0 (GtkTargetEntry, *n_targets);
626 for (i = 0, tmp_list = list->list;
628 i++, tmp_list = g_list_next (tmp_list))
630 GtkTargetPair *pair = tmp_list->data;
632 targets[i].target = gdk_atom_name (pair->target);
633 targets[i].flags = pair->flags;
634 targets[i].info = pair->info;
641 * gtk_target_table_free:
642 * @targets: (array length=n_targets): a #GtkTargetEntry array
643 * @n_targets: the number of entries in the array
645 * This function frees a target table as returned by
646 * gtk_target_table_new_from_list()
651 gtk_target_table_free (GtkTargetEntry *targets,
656 g_return_if_fail (targets == NULL || n_targets > 0);
658 for (i = 0; i < n_targets; i++)
659 g_free (targets[i].target);
665 * gtk_selection_owner_set_for_display:
666 * @display: the #Gdkdisplay where the selection is set
667 * @widget: (allow-none): new selection owner (a #GdkWidget), or %NULL.
668 * @selection: an interned atom representing the selection to claim.
669 * @time_: timestamp with which to claim the selection
671 * Claim ownership of a given selection for a particular widget, or,
672 * if @widget is %NULL, release ownership of the selection.
674 * Return value: TRUE if the operation succeeded
679 gtk_selection_owner_set_for_display (GdkDisplay *display,
685 GtkWidget *old_owner;
686 GtkSelectionInfo *selection_info = NULL;
689 g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE);
690 g_return_val_if_fail (selection != GDK_NONE, FALSE);
691 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
692 g_return_val_if_fail (widget == NULL || gtk_widget_get_display (widget) == display, FALSE);
697 window = gtk_widget_get_window (widget);
699 tmp_list = current_selections;
702 if (((GtkSelectionInfo *)tmp_list->data)->selection == selection)
704 selection_info = tmp_list->data;
708 tmp_list = tmp_list->next;
711 if (gdk_selection_owner_set_for_display (display, window, selection, time, TRUE))
719 old_owner = selection_info->widget;
720 current_selections = g_list_remove_link (current_selections,
722 g_list_free (tmp_list);
723 g_slice_free (GtkSelectionInfo, selection_info);
728 if (selection_info == NULL)
730 selection_info = g_slice_new (GtkSelectionInfo);
731 selection_info->selection = selection;
732 selection_info->widget = widget;
733 selection_info->time = time;
734 selection_info->display = display;
735 current_selections = g_list_prepend (current_selections,
740 old_owner = selection_info->widget;
741 selection_info->widget = widget;
742 selection_info->time = time;
743 selection_info->display = display;
746 /* If another widget in the application lost the selection,
747 * send it a GDK_SELECTION_CLEAR event.
749 if (old_owner && old_owner != widget)
751 GdkEvent *event = gdk_event_new (GDK_SELECTION_CLEAR);
753 event->selection.window = g_object_ref (gtk_widget_get_window (old_owner));
754 event->selection.selection = selection;
755 event->selection.time = time;
757 gtk_widget_event (old_owner, event);
759 gdk_event_free (event);
768 * gtk_selection_owner_set:
769 * @widget: (allow-none): a #GtkWidget, or %NULL.
770 * @selection: an interned atom representing the selection to claim
771 * @time_: timestamp with which to claim the selection
773 * Claims ownership of a given selection for a particular widget,
774 * or, if @widget is %NULL, release ownership of the selection.
776 * Return value: %TRUE if the operation succeeded
779 gtk_selection_owner_set (GtkWidget *widget,
785 g_return_val_if_fail (widget == NULL || gtk_widget_get_realized (widget), FALSE);
786 g_return_val_if_fail (selection != GDK_NONE, FALSE);
789 display = gtk_widget_get_display (widget);
793 g_warning ("gtk_selection_owner_set (NULL,...) is not multihead safe"));
795 display = gdk_display_get_default ();
798 return gtk_selection_owner_set_for_display (display, widget,
802 typedef struct _GtkSelectionTargetList GtkSelectionTargetList;
804 struct _GtkSelectionTargetList {
809 static GtkTargetList *
810 gtk_selection_target_list_get (GtkWidget *widget,
813 GtkSelectionTargetList *sellist;
817 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
822 sellist = tmp_list->data;
823 if (sellist->selection == selection)
824 return sellist->list;
825 tmp_list = tmp_list->next;
828 sellist = g_slice_new (GtkSelectionTargetList);
829 sellist->selection = selection;
830 sellist->list = gtk_target_list_new (NULL, 0);
832 lists = g_list_prepend (lists, sellist);
833 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
835 return sellist->list;
839 gtk_selection_target_list_remove (GtkWidget *widget)
841 GtkSelectionTargetList *sellist;
845 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
850 sellist = tmp_list->data;
852 gtk_target_list_unref (sellist->list);
854 g_slice_free (GtkSelectionTargetList, sellist);
855 tmp_list = tmp_list->next;
859 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), NULL);
863 * gtk_selection_clear_targets:
864 * @widget: a #GtkWidget
865 * @selection: an atom representing a selection
867 * Remove all targets registered for the given selection for the
871 gtk_selection_clear_targets (GtkWidget *widget,
874 GtkSelectionTargetList *sellist;
878 g_return_if_fail (GTK_IS_WIDGET (widget));
879 g_return_if_fail (selection != GDK_NONE);
881 lists = g_object_get_data (G_OBJECT (widget), gtk_selection_handler_key);
886 sellist = tmp_list->data;
887 if (sellist->selection == selection)
889 lists = g_list_delete_link (lists, tmp_list);
890 gtk_target_list_unref (sellist->list);
891 g_slice_free (GtkSelectionTargetList, sellist);
896 tmp_list = tmp_list->next;
899 g_object_set_data (G_OBJECT (widget), I_(gtk_selection_handler_key), lists);
903 * gtk_selection_add_target:
904 * @widget: a #GtkTarget
905 * @selection: the selection
906 * @target: target to add.
907 * @info: A unsigned integer which will be passed back to the application.
909 * Appends a specified target to the list of supported targets for a
910 * given widget and selection.
913 gtk_selection_add_target (GtkWidget *widget,
920 g_return_if_fail (GTK_IS_WIDGET (widget));
921 g_return_if_fail (selection != GDK_NONE);
923 list = gtk_selection_target_list_get (widget, selection);
924 gtk_target_list_add (list, target, 0, info);
925 #ifdef GDK_WINDOWING_WIN32
926 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, 1, &target);
931 * gtk_selection_add_targets:
932 * @widget: a #GtkWidget
933 * @selection: the selection
934 * @targets: (array length=ntargets): a table of targets to add
935 * @ntargets: number of entries in @targets
937 * Prepends a table of targets to the list of supported targets
938 * for a given widget and selection.
941 gtk_selection_add_targets (GtkWidget *widget,
943 const GtkTargetEntry *targets,
948 g_return_if_fail (GTK_IS_WIDGET (widget));
949 g_return_if_fail (selection != GDK_NONE);
950 g_return_if_fail (targets != NULL);
952 list = gtk_selection_target_list_get (widget, selection);
953 gtk_target_list_add_table (list, targets, ntargets);
955 #ifdef GDK_WINDOWING_WIN32
958 GdkAtom *atoms = g_new (GdkAtom, ntargets);
960 for (i = 0; i < ntargets; ++i)
961 atoms[i] = gdk_atom_intern (targets[i].target, FALSE);
962 gdk_win32_selection_add_targets (gtk_widget_get_window (widget), selection, ntargets, atoms);
970 * gtk_selection_remove_all:
971 * @widget: a #GtkWidget
973 * Removes all handlers and unsets ownership of all
974 * selections for a widget. Called when widget is being
975 * destroyed. This function will not generally be
976 * called by applications.
979 gtk_selection_remove_all (GtkWidget *widget)
983 GtkSelectionInfo *selection_info;
985 g_return_if_fail (GTK_IS_WIDGET (widget));
987 /* Remove pending requests/incrs for this widget */
989 tmp_list = current_retrievals;
992 next = tmp_list->next;
993 if (((GtkRetrievalInfo *)tmp_list->data)->widget == widget)
995 current_retrievals = g_list_remove_link (current_retrievals,
997 /* structure will be freed in timeout */
998 g_list_free (tmp_list);
1003 /* Disclaim ownership of any selections */
1005 tmp_list = current_selections;
1008 next = tmp_list->next;
1009 selection_info = (GtkSelectionInfo *)tmp_list->data;
1011 if (selection_info->widget == widget)
1013 gdk_selection_owner_set_for_display (selection_info->display,
1015 selection_info->selection,
1016 GDK_CURRENT_TIME, FALSE);
1017 current_selections = g_list_remove_link (current_selections,
1019 g_list_free (tmp_list);
1020 g_slice_free (GtkSelectionInfo, selection_info);
1026 /* Remove all selection lists */
1027 gtk_selection_target_list_remove (widget);
1032 * gtk_selection_convert:
1033 * @widget: The widget which acts as requestor
1034 * @selection: Which selection to get
1035 * @target: Form of information desired (e.g., STRING)
1036 * @time_: Time of request (usually of triggering event)
1037 In emergency, you could use #GDK_CURRENT_TIME
1039 * Requests the contents of a selection. When received,
1040 * a "selection-received" signal will be generated.
1042 * Return value: %TRUE if requested succeeded. %FALSE if we could not process
1043 * request. (e.g., there was already a request in process for
1047 gtk_selection_convert (GtkWidget *widget,
1052 GtkRetrievalInfo *info;
1054 GdkWindow *owner_window;
1055 GdkDisplay *display;
1057 g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
1058 g_return_val_if_fail (selection != GDK_NONE, FALSE);
1061 gtk_selection_init ();
1063 if (!gtk_widget_get_realized (widget))
1064 gtk_widget_realize (widget);
1066 /* Check to see if there are already any retrievals in progress for
1067 this widget. If we changed GDK to use the selection for the
1068 window property in which to store the retrieved information, then
1069 we could support multiple retrievals for different selections.
1070 This might be useful for DND. */
1072 tmp_list = current_retrievals;
1075 info = (GtkRetrievalInfo *)tmp_list->data;
1076 if (info->widget == widget)
1078 tmp_list = tmp_list->next;
1081 info = g_slice_new (GtkRetrievalInfo);
1083 info->widget = widget;
1084 info->selection = selection;
1085 info->target = target;
1086 info->idle_time = 0;
1087 info->buffer = NULL;
1090 /* Check if this process has current owner. If so, call handler
1091 procedure directly to avoid deadlocks with INCR. */
1093 display = gtk_widget_get_display (widget);
1094 owner_window = gdk_selection_owner_get_for_display (display, selection);
1096 if (owner_window != NULL)
1098 GtkWidget *owner_widget;
1099 gpointer owner_widget_ptr;
1100 GtkSelectionData selection_data;
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: (transfer none): 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: (transfer none): 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: (transfer none): 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: (out): 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 length=length): 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: (array zero-terminated=1): a %NULL-terminated array of
1756 * strings holding URIs
1758 * Sets the contents of the selection from a list of URIs.
1759 * The string is converted to the form determined by
1760 * @selection_data->target.
1762 * Return value: %TRUE if the selection was successfully set,
1768 gtk_selection_data_set_uris (GtkSelectionData *selection_data,
1771 g_return_val_if_fail (selection_data != NULL, FALSE);
1772 g_return_val_if_fail (uris != NULL, FALSE);
1776 if (selection_data->target == text_uri_list_atom)
1783 list = g_string_new (NULL);
1784 for (i = 0; uris[i]; i++)
1786 g_string_append (list, uris[i]);
1787 g_string_append (list, "\r\n");
1790 result = g_convert (list->str, list->len,
1792 NULL, &length, NULL);
1793 g_string_free (list, TRUE);
1797 gtk_selection_data_set (selection_data,
1799 8, (guchar *)result, length);
1811 * gtk_selection_data_get_uris:
1812 * @selection_data: a #GtkSelectionData
1814 * Gets the contents of the selection data as array of URIs.
1816 * Return value: (array zero-terminated=1) (element-type utf8) (transfer full): if
1817 * the selection data contains a list of
1818 * URIs, a newly allocated %NULL-terminated string array
1819 * containing the URIs, otherwise %NULL. If the result is
1820 * non-%NULL it must be freed with g_strfreev().
1825 gtk_selection_data_get_uris (const GtkSelectionData *selection_data)
1827 gchar **result = NULL;
1829 g_return_val_if_fail (selection_data != NULL, NULL);
1833 if (selection_data->length >= 0 &&
1834 selection_data->type == text_uri_list_atom)
1837 gint count = gdk_text_property_to_utf8_list_for_display (selection_data->display,
1839 selection_data->format,
1840 selection_data->data,
1841 selection_data->length,
1844 result = g_uri_list_extract_uris (list[0]);
1854 * gtk_selection_data_get_targets:
1855 * @selection_data: a #GtkSelectionData object
1856 * @targets: (out) (array length=n_atoms) (transfer container):
1857 * location to store an array of targets. The result stored
1858 * here must be freed with g_free().
1859 * @n_atoms: location to store number of items in @targets.
1861 * Gets the contents of @selection_data as an array of targets.
1862 * This can be used to interpret the results of getting
1863 * the standard TARGETS target that is always supplied for
1866 * Return value: %TRUE if @selection_data contains a valid
1867 * array of targets, otherwise %FALSE.
1870 gtk_selection_data_get_targets (const GtkSelectionData *selection_data,
1874 g_return_val_if_fail (selection_data != NULL, FALSE);
1876 if (selection_data->length >= 0 &&
1877 selection_data->format == 32 &&
1878 selection_data->type == GDK_SELECTION_TYPE_ATOM)
1881 *targets = g_memdup (selection_data->data, selection_data->length);
1883 *n_atoms = selection_data->length / sizeof (GdkAtom);
1899 * gtk_targets_include_text:
1900 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1901 * @n_targets: the length of @targets
1903 * Determines if any of the targets in @targets can be used to
1906 * Return value: %TRUE if @targets include a suitable target for text,
1912 gtk_targets_include_text (GdkAtom *targets,
1916 gboolean result = FALSE;
1918 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1920 /* Keep in sync with gtk_target_list_add_text_targets()
1925 for (i = 0; i < n_targets; i++)
1927 if (targets[i] == utf8_atom ||
1928 targets[i] == text_atom ||
1929 targets[i] == GDK_TARGET_STRING ||
1930 targets[i] == ctext_atom ||
1931 targets[i] == text_plain_atom ||
1932 targets[i] == text_plain_utf8_atom ||
1933 targets[i] == text_plain_locale_atom)
1944 * gtk_targets_include_rich_text:
1945 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
1946 * @n_targets: the length of @targets
1947 * @buffer: a #GtkTextBuffer
1949 * Determines if any of the targets in @targets can be used to
1950 * provide rich text.
1952 * Return value: %TRUE if @targets include a suitable target for rich text,
1958 gtk_targets_include_rich_text (GdkAtom *targets,
1960 GtkTextBuffer *buffer)
1962 GdkAtom *rich_targets;
1963 gint n_rich_targets;
1965 gboolean result = FALSE;
1967 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
1968 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1972 rich_targets = gtk_text_buffer_get_deserialize_formats (buffer,
1975 for (i = 0; i < n_targets; i++)
1977 for (j = 0; j < n_rich_targets; j++)
1979 if (targets[i] == rich_targets[j])
1988 g_free (rich_targets);
1994 * gtk_selection_data_targets_include_text:
1995 * @selection_data: a #GtkSelectionData object
1997 * Given a #GtkSelectionData object holding a list of targets,
1998 * determines if any of the targets in @targets can be used to
2001 * Return value: %TRUE if @selection_data holds a list of targets,
2002 * and a suitable target for text is included, otherwise %FALSE.
2005 gtk_selection_data_targets_include_text (const GtkSelectionData *selection_data)
2009 gboolean result = FALSE;
2011 g_return_val_if_fail (selection_data != NULL, FALSE);
2015 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2017 result = gtk_targets_include_text (targets, n_targets);
2025 * gtk_selection_data_targets_include_rich_text:
2026 * @selection_data: a #GtkSelectionData object
2027 * @buffer: a #GtkTextBuffer
2029 * Given a #GtkSelectionData object holding a list of targets,
2030 * determines if any of the targets in @targets can be used to
2031 * provide rich text.
2033 * Return value: %TRUE if @selection_data holds a list of targets,
2034 * and a suitable target for rich text is included,
2040 gtk_selection_data_targets_include_rich_text (const GtkSelectionData *selection_data,
2041 GtkTextBuffer *buffer)
2045 gboolean result = FALSE;
2047 g_return_val_if_fail (selection_data != NULL, FALSE);
2048 g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
2052 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2054 result = gtk_targets_include_rich_text (targets, n_targets, buffer);
2062 * gtk_targets_include_image:
2063 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2064 * @n_targets: the length of @targets
2065 * @writable: whether to accept only targets for which GTK+ knows
2066 * how to convert a pixbuf into the format
2068 * Determines if any of the targets in @targets can be used to
2069 * provide a #GdkPixbuf.
2071 * Return value: %TRUE if @targets include a suitable target for images,
2077 gtk_targets_include_image (GdkAtom *targets,
2081 GtkTargetList *list;
2084 gboolean result = FALSE;
2086 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2088 list = gtk_target_list_new (NULL, 0);
2089 gtk_target_list_add_image_targets (list, 0, writable);
2090 for (i = 0; i < n_targets && !result; i++)
2092 for (l = list->list; l; l = l->next)
2094 GtkTargetPair *pair = (GtkTargetPair *)l->data;
2095 if (pair->target == targets[i])
2102 gtk_target_list_unref (list);
2108 * gtk_selection_data_targets_include_image:
2109 * @selection_data: a #GtkSelectionData object
2110 * @writable: whether to accept only targets for which GTK+ knows
2111 * how to convert a pixbuf into the format
2113 * Given a #GtkSelectionData object holding a list of targets,
2114 * determines if any of the targets in @targets can be used to
2115 * provide a #GdkPixbuf.
2117 * Return value: %TRUE if @selection_data holds a list of targets,
2118 * and a suitable target for images is included, otherwise %FALSE.
2123 gtk_selection_data_targets_include_image (const GtkSelectionData *selection_data,
2128 gboolean result = FALSE;
2130 g_return_val_if_fail (selection_data != NULL, FALSE);
2134 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2136 result = gtk_targets_include_image (targets, n_targets, writable);
2144 * gtk_targets_include_uri:
2145 * @targets: (array length=n_targets): an array of #GdkAtom<!-- -->s
2146 * @n_targets: the length of @targets
2148 * Determines if any of the targets in @targets can be used to
2149 * provide an uri list.
2151 * Return value: %TRUE if @targets include a suitable target for uri lists,
2157 gtk_targets_include_uri (GdkAtom *targets,
2161 gboolean result = FALSE;
2163 g_return_val_if_fail (targets != NULL || n_targets == 0, FALSE);
2165 /* Keep in sync with gtk_target_list_add_uri_targets()
2170 for (i = 0; i < n_targets; i++)
2172 if (targets[i] == text_uri_list_atom)
2183 * gtk_selection_data_targets_include_uri:
2184 * @selection_data: a #GtkSelectionData object
2186 * Given a #GtkSelectionData object holding a list of targets,
2187 * determines if any of the targets in @targets can be used to
2188 * provide a list or URIs.
2190 * Return value: %TRUE if @selection_data holds a list of targets,
2191 * and a suitable target for URI lists is included, otherwise %FALSE.
2196 gtk_selection_data_targets_include_uri (const GtkSelectionData *selection_data)
2200 gboolean result = FALSE;
2202 g_return_val_if_fail (selection_data != NULL, FALSE);
2206 if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
2208 result = gtk_targets_include_uri (targets, n_targets);
2216 /*************************************************************
2217 * gtk_selection_init:
2218 * Initialize local variables
2222 *************************************************************/
2225 gtk_selection_init (void)
2227 gtk_selection_atoms[INCR] = gdk_atom_intern_static_string ("INCR");
2228 gtk_selection_atoms[MULTIPLE] = gdk_atom_intern_static_string ("MULTIPLE");
2229 gtk_selection_atoms[TIMESTAMP] = gdk_atom_intern_static_string ("TIMESTAMP");
2230 gtk_selection_atoms[TARGETS] = gdk_atom_intern_static_string ("TARGETS");
2231 gtk_selection_atoms[SAVE_TARGETS] = gdk_atom_intern_static_string ("SAVE_TARGETS");
2237 * _gtk_selection_clear:
2238 * @widget: a #GtkWidget
2241 * The default handler for the #GtkWidget::selection-clear-event
2244 * Return value: %TRUE if the event was handled, otherwise false
2247 _gtk_selection_clear (GtkWidget *widget,
2248 GdkEventSelection *event)
2250 /* Note that we filter clear events in gdkselection-x11.c, so
2251 * that we only will get here if the clear event actually
2252 * represents a change that we didn't do ourself.
2255 GtkSelectionInfo *selection_info = NULL;
2257 tmp_list = current_selections;
2260 selection_info = (GtkSelectionInfo *)tmp_list->data;
2262 if ((selection_info->selection == event->selection) &&
2263 (selection_info->widget == widget))
2266 tmp_list = tmp_list->next;
2271 current_selections = g_list_remove_link (current_selections, tmp_list);
2272 g_list_free (tmp_list);
2273 g_slice_free (GtkSelectionInfo, selection_info);
2280 /*************************************************************
2281 * _gtk_selection_request:
2282 * Handler for "selection_request_event"
2287 *************************************************************/
2290 _gtk_selection_request (GtkWidget *widget,
2291 GdkEventSelection *event)
2293 GdkDisplay *display = gtk_widget_get_display (widget);
2297 gulong selection_max_size;
2300 gtk_selection_init ();
2302 selection_max_size = GTK_SELECTION_MAX_SIZE (display);
2304 /* Check if we own selection */
2306 tmp_list = current_selections;
2309 GtkSelectionInfo *selection_info = (GtkSelectionInfo *)tmp_list->data;
2311 if ((selection_info->selection == event->selection) &&
2312 (selection_info->widget == widget))
2315 tmp_list = tmp_list->next;
2318 if (tmp_list == NULL)
2321 info = g_slice_new (GtkIncrInfo);
2323 g_object_ref (widget);
2325 info->selection = event->selection;
2326 info->num_incrs = 0;
2327 info->requestor = g_object_ref (event->requestor);
2329 /* Determine conversions we need to perform */
2330 if (event->target == gtk_selection_atoms[MULTIPLE])
2339 gdk_error_trap_push ();
2340 if (!gdk_property_get (info->requestor, event->property, GDK_NONE, /* AnyPropertyType */
2341 0, selection_max_size, FALSE,
2342 &type, &format, &length, &mult_atoms))
2344 gdk_selection_send_notify_for_display (display,
2350 g_free (mult_atoms);
2351 g_slice_free (GtkIncrInfo, info);
2352 gdk_error_trap_pop_ignored ();
2355 gdk_error_trap_pop_ignored ();
2357 /* This is annoying; the ICCCM doesn't specify the property type
2358 * used for the property contents, so the autoconversion for
2359 * ATOM / ATOM_PAIR in GDK doesn't work properly.
2361 #ifdef GDK_WINDOWING_X11
2362 if (type != GDK_SELECTION_TYPE_ATOM &&
2363 type != gdk_atom_intern_static_string ("ATOM_PAIR"))
2365 info->num_conversions = length / (2*sizeof (glong));
2366 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2368 for (i=0; i<info->num_conversions; i++)
2370 info->conversions[i].target = gdk_x11_xatom_to_atom_for_display (display,
2371 ((glong *)mult_atoms)[2*i]);
2372 info->conversions[i].property = gdk_x11_xatom_to_atom_for_display (display,
2373 ((glong *)mult_atoms)[2*i + 1]);
2376 g_free (mult_atoms);
2381 info->num_conversions = length / (2*sizeof (GdkAtom));
2382 info->conversions = g_new (GtkIncrConversion, info->num_conversions);
2384 for (i=0; i<info->num_conversions; i++)
2386 info->conversions[i].target = ((GdkAtom *)mult_atoms)[2*i];
2387 info->conversions[i].property = ((GdkAtom *)mult_atoms)[2*i+1];
2390 g_free (mult_atoms);
2393 else /* only a single conversion */
2395 info->conversions = g_new (GtkIncrConversion, 1);
2396 info->num_conversions = 1;
2397 info->conversions[0].target = event->target;
2398 info->conversions[0].property = event->property;
2401 /* Loop through conversions and determine which of these are big
2402 enough to require doing them via INCR */
2403 for (i=0; i<info->num_conversions; i++)
2405 GtkSelectionData data;
2408 data.selection = event->selection;
2409 data.target = info->conversions[i].target;
2412 data.display = gtk_widget_get_display (widget);
2414 #ifdef DEBUG_SELECTION
2415 g_message ("Selection %ld, target %ld (%s) requested by 0x%x (property = %ld)",
2417 info->conversions[i].target,
2418 gdk_atom_name (info->conversions[i].target),
2419 event->requestor, info->conversions[i].property);
2422 gtk_selection_invoke_handler (widget, &data, event->time);
2423 if (data.length < 0)
2425 info->conversions[i].property = GDK_NONE;
2429 g_return_val_if_fail ((data.format >= 8) && (data.format % 8 == 0), FALSE);
2431 items = data.length / gtk_selection_bytes_per_item (data.format);
2433 if (data.length > selection_max_size)
2435 /* Sending via INCR */
2436 #ifdef DEBUG_SELECTION
2437 g_message ("Target larger (%d) than max. request size (%ld), sending incrementally\n",
2438 data.length, selection_max_size);
2441 info->conversions[i].offset = 0;
2442 info->conversions[i].data = data;
2445 gdk_property_change (info->requestor,
2446 info->conversions[i].property,
2447 gtk_selection_atoms[INCR],
2449 GDK_PROP_MODE_REPLACE,
2450 (guchar *)&items, 1);
2454 info->conversions[i].offset = -1;
2456 gdk_property_change (info->requestor,
2457 info->conversions[i].property,
2460 GDK_PROP_MODE_REPLACE,
2467 /* If we have some INCR's, we need to send the rest of the data in
2470 if (info->num_incrs > 0)
2472 /* FIXME: this could be dangerous if window doesn't still
2475 #ifdef DEBUG_SELECTION
2476 g_message ("Starting INCR...");
2479 gdk_window_set_events (info->requestor,
2480 gdk_window_get_events (info->requestor) |
2481 GDK_PROPERTY_CHANGE_MASK);
2482 current_incrs = g_list_append (current_incrs, info);
2483 gdk_threads_add_timeout (1000, (GSourceFunc) gtk_selection_incr_timeout, info);
2486 /* If it was a MULTIPLE request, set the property to indicate which
2487 conversions succeeded */
2488 if (event->target == gtk_selection_atoms[MULTIPLE])
2490 GdkAtom *mult_atoms = g_new (GdkAtom, 2 * info->num_conversions);
2491 for (i = 0; i < info->num_conversions; i++)
2493 mult_atoms[2*i] = info->conversions[i].target;
2494 mult_atoms[2*i+1] = info->conversions[i].property;
2497 gdk_property_change (info->requestor, event->property,
2498 gdk_atom_intern_static_string ("ATOM_PAIR"), 32,
2499 GDK_PROP_MODE_REPLACE,
2500 (guchar *)mult_atoms, 2*info->num_conversions);
2501 g_free (mult_atoms);
2504 if (info->num_conversions == 1 &&
2505 info->conversions[0].property == GDK_NONE)
2507 /* Reject the entire conversion */
2508 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2517 gdk_selection_send_notify_for_display (gtk_widget_get_display (widget),
2525 if (info->num_incrs == 0)
2527 g_free (info->conversions);
2528 g_slice_free (GtkIncrInfo, info);
2531 g_object_unref (widget);
2536 /*************************************************************
2537 * _gtk_selection_incr_event:
2538 * Called whenever an PropertyNotify event occurs for an
2539 * GdkWindow with user_data == NULL. These will be notifications
2540 * that a window we are sending the selection to via the
2541 * INCR protocol has deleted a property and is ready for
2545 * window: the requestor window
2546 * event: the property event structure
2549 *************************************************************/
2552 _gtk_selection_incr_event (GdkWindow *window,
2553 GdkEventProperty *event)
2556 GtkIncrInfo *info = NULL;
2559 gulong selection_max_size;
2563 if (event->state != GDK_PROPERTY_DELETE)
2566 #ifdef DEBUG_SELECTION
2567 g_message ("PropertyDelete, property %ld", event->atom);
2570 selection_max_size = GTK_SELECTION_MAX_SIZE (gdk_window_get_display (window));
2572 /* Now find the appropriate ongoing INCR */
2573 tmp_list = current_incrs;
2576 info = (GtkIncrInfo *)tmp_list->data;
2577 if (info->requestor == event->window)
2580 tmp_list = tmp_list->next;
2583 if (tmp_list == NULL)
2586 /* Find out which target this is for */
2587 for (i=0; i<info->num_conversions; i++)
2589 if (info->conversions[i].property == event->atom &&
2590 info->conversions[i].offset != -1)
2594 info->idle_time = 0;
2596 if (info->conversions[i].offset == -2) /* only the last 0-length
2604 num_bytes = info->conversions[i].data.length -
2605 info->conversions[i].offset;
2606 buffer = info->conversions[i].data.data +
2607 info->conversions[i].offset;
2609 if (num_bytes > selection_max_size)
2611 num_bytes = selection_max_size;
2612 info->conversions[i].offset += selection_max_size;
2615 info->conversions[i].offset = -2;
2617 #ifdef DEBUG_SELECTION
2618 g_message ("INCR: put %d bytes (offset = %d) into window 0x%lx , property %ld",
2619 num_bytes, info->conversions[i].offset,
2620 GDK_WINDOW_XID(info->requestor), event->atom);
2623 bytes_per_item = gtk_selection_bytes_per_item (info->conversions[i].data.format);
2624 gdk_property_change (info->requestor, event->atom,
2625 info->conversions[i].data.type,
2626 info->conversions[i].data.format,
2627 GDK_PROP_MODE_REPLACE,
2629 num_bytes / bytes_per_item);
2631 if (info->conversions[i].offset == -2)
2633 g_free (info->conversions[i].data.data);
2634 info->conversions[i].data.data = NULL;
2640 info->conversions[i].offset = -1;
2645 /* Check if we're finished with all the targets */
2647 if (info->num_incrs == 0)
2649 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2650 g_list_free (tmp_list);
2651 /* Let the timeout free it */
2657 /*************************************************************
2658 * gtk_selection_incr_timeout:
2659 * Timeout callback for the sending portion of the INCR
2662 * info: Information about this incr
2664 *************************************************************/
2667 gtk_selection_incr_timeout (GtkIncrInfo *info)
2672 /* Determine if retrieval has finished by checking if it still in
2673 list of pending retrievals */
2675 tmp_list = current_incrs;
2678 if (info == (GtkIncrInfo *)tmp_list->data)
2680 tmp_list = tmp_list->next;
2683 /* If retrieval is finished */
2684 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2686 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2688 current_incrs = g_list_remove_link (current_incrs, tmp_list);
2689 g_list_free (tmp_list);
2692 g_free (info->conversions);
2693 /* FIXME: we should check if requestor window is still in use,
2694 and if not, remove it? */
2696 g_slice_free (GtkIncrInfo, info);
2698 retval = FALSE; /* remove timeout */
2704 retval = TRUE; /* timeout will happen again */
2710 /*************************************************************
2711 * _gtk_selection_notify:
2712 * Handler for "selection-notify-event" signals on windows
2713 * where a retrieval is currently in process. The selection
2714 * owner has responded to our conversion request.
2716 * widget: Widget getting signal
2717 * event: Selection event structure
2718 * info: Information about this retrieval
2720 * was event handled?
2721 *************************************************************/
2724 _gtk_selection_notify (GtkWidget *widget,
2725 GdkEventSelection *event)
2728 GtkRetrievalInfo *info = NULL;
2730 guchar *buffer = NULL;
2735 #ifdef DEBUG_SELECTION
2736 g_message ("Initial receipt of selection %ld, target %ld (property = %ld)",
2737 event->selection, event->target, event->property);
2740 window = gtk_widget_get_window (widget);
2742 tmp_list = current_retrievals;
2745 info = (GtkRetrievalInfo *)tmp_list->data;
2746 if (info->widget == widget && info->selection == event->selection)
2748 tmp_list = tmp_list->next;
2751 if (!tmp_list) /* no retrieval in progress */
2754 if (event->property != GDK_NONE)
2755 length = gdk_selection_property_get (window, &buffer,
2758 length = 0; /* silence gcc */
2760 if (event->property == GDK_NONE || buffer == NULL)
2762 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2763 g_list_free (tmp_list);
2764 /* structure will be freed in timeout */
2765 gtk_selection_retrieval_report (info,
2766 GDK_NONE, 0, NULL, -1, event->time);
2771 if (type == gtk_selection_atoms[INCR])
2773 /* The remainder of the selection will come through PropertyNotify
2776 info->notify_time = event->time;
2777 info->idle_time = 0;
2778 info->offset = 0; /* Mark as OK to proceed */
2779 gdk_window_set_events (window,
2780 gdk_window_get_events (window)
2781 | GDK_PROPERTY_CHANGE_MASK);
2785 /* We don't delete the info structure - that will happen in timeout */
2786 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2787 g_list_free (tmp_list);
2789 info->offset = length;
2790 gtk_selection_retrieval_report (info,
2792 buffer, length, event->time);
2795 gdk_property_delete (window, event->property);
2802 /*************************************************************
2803 * _gtk_selection_property_notify:
2804 * Handler for "property-notify-event" signals on windows
2805 * where a retrieval is currently in process. The selection
2806 * owner has added more data.
2808 * widget: Widget getting signal
2809 * event: Property event structure
2810 * info: Information about this retrieval
2812 * was event handled?
2813 *************************************************************/
2816 _gtk_selection_property_notify (GtkWidget *widget,
2817 GdkEventProperty *event)
2820 GtkRetrievalInfo *info = NULL;
2827 g_return_val_if_fail (widget != NULL, FALSE);
2828 g_return_val_if_fail (event != NULL, FALSE);
2830 #if defined(GDK_WINDOWING_WIN32) || defined(GDK_WINDOWING_X11)
2831 if ((event->state != GDK_PROPERTY_NEW_VALUE) || /* property was deleted */
2832 (event->atom != gdk_atom_intern_static_string ("GDK_SELECTION"))) /* not the right property */
2836 #ifdef DEBUG_SELECTION
2837 g_message ("PropertyNewValue, property %ld",
2841 tmp_list = current_retrievals;
2844 info = (GtkRetrievalInfo *)tmp_list->data;
2845 if (info->widget == widget)
2847 tmp_list = tmp_list->next;
2850 if (!tmp_list) /* No retrieval in progress */
2853 if (info->offset < 0) /* We haven't got the SelectionNotify
2854 for this retrieval yet */
2857 info->idle_time = 0;
2859 window = gtk_widget_get_window (widget);
2860 length = gdk_selection_property_get (window, &new_buffer,
2862 gdk_property_delete (window, event->atom);
2864 /* We could do a lot better efficiency-wise by paying attention to
2865 what length was sent in the initial INCR transaction, instead of
2866 doing memory allocation at every step. But its only guaranteed to
2867 be a _lower bound_ (pretty useless!) */
2869 if (length == 0 || type == GDK_NONE) /* final zero length portion */
2871 /* Info structure will be freed in timeout */
2872 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2873 g_list_free (tmp_list);
2874 gtk_selection_retrieval_report (info,
2876 (type == GDK_NONE) ? NULL : info->buffer,
2877 (type == GDK_NONE) ? -1 : info->offset,
2880 else /* append on newly arrived data */
2884 #ifdef DEBUG_SELECTION
2885 g_message ("Start - Adding %d bytes at offset 0",
2888 info->buffer = new_buffer;
2889 info->offset = length;
2894 #ifdef DEBUG_SELECTION
2895 g_message ("Appending %d bytes at offset %d",
2896 length,info->offset);
2898 /* We copy length+1 bytes to preserve guaranteed null termination */
2899 info->buffer = g_realloc (info->buffer, info->offset+length+1);
2900 memcpy (info->buffer + info->offset, new_buffer, length+1);
2901 info->offset += length;
2902 g_free (new_buffer);
2909 /*************************************************************
2910 * gtk_selection_retrieval_timeout:
2911 * Timeout callback while receiving a selection.
2913 * info: Information about this retrieval
2915 *************************************************************/
2918 gtk_selection_retrieval_timeout (GtkRetrievalInfo *info)
2923 /* Determine if retrieval has finished by checking if it still in
2924 list of pending retrievals */
2926 tmp_list = current_retrievals;
2929 if (info == (GtkRetrievalInfo *)tmp_list->data)
2931 tmp_list = tmp_list->next;
2934 /* If retrieval is finished */
2935 if (!tmp_list || info->idle_time >= IDLE_ABORT_TIME)
2937 if (tmp_list && info->idle_time >= IDLE_ABORT_TIME)
2939 current_retrievals = g_list_remove_link (current_retrievals, tmp_list);
2940 g_list_free (tmp_list);
2941 gtk_selection_retrieval_report (info, GDK_NONE, 0, NULL, -1, GDK_CURRENT_TIME);
2944 g_free (info->buffer);
2945 g_slice_free (GtkRetrievalInfo, info);
2947 retval = FALSE; /* remove timeout */
2953 retval = TRUE; /* timeout will happen again */
2959 /*************************************************************
2960 * gtk_selection_retrieval_report:
2961 * Emits a "selection-received" signal.
2963 * info: information about the retrieval that completed
2964 * buffer: buffer containing data (NULL => errror)
2965 * time: timestamp for data in buffer
2967 *************************************************************/
2970 gtk_selection_retrieval_report (GtkRetrievalInfo *info,
2971 GdkAtom type, gint format,
2972 guchar *buffer, gint length,
2975 GtkSelectionData data;
2977 data.selection = info->selection;
2978 data.target = info->target;
2980 data.format = format;
2982 data.length = length;
2984 data.display = gtk_widget_get_display (info->widget);
2986 g_signal_emit_by_name (info->widget,
2987 "selection-received",
2991 /*************************************************************
2992 * gtk_selection_invoke_handler:
2993 * Finds and invokes handler for specified
2994 * widget/selection/target combination, calls
2995 * gtk_selection_default_handler if none exists.
2998 * widget: selection owner
2999 * data: selection data [INOUT]
3000 * time: time from requeset
3003 * Number of bytes written to buffer, -1 if error
3004 *************************************************************/
3007 gtk_selection_invoke_handler (GtkWidget *widget,
3008 GtkSelectionData *data,
3011 GtkTargetList *target_list;
3015 g_return_if_fail (widget != NULL);
3017 target_list = gtk_selection_target_list_get (widget, data->selection);
3018 if (data->target != gtk_selection_atoms[SAVE_TARGETS] &&
3020 gtk_target_list_find (target_list, data->target, &info))
3022 g_signal_emit_by_name (widget,
3028 gtk_selection_default_handler (widget, data);
3031 /*************************************************************
3032 * gtk_selection_default_handler:
3033 * Handles some default targets that exist for any widget
3034 * If it can't fit results into buffer, returns -1. This
3035 * won't happen in any conceivable case, since it would
3036 * require 1000 selection targets!
3039 * widget: selection owner
3040 * data: selection data [INOUT]
3042 *************************************************************/
3045 gtk_selection_default_handler (GtkWidget *widget,
3046 GtkSelectionData *data)
3048 if (data->target == gtk_selection_atoms[TIMESTAMP])
3050 /* Time which was used to obtain selection */
3052 GtkSelectionInfo *selection_info;
3054 tmp_list = current_selections;
3057 selection_info = (GtkSelectionInfo *)tmp_list->data;
3058 if ((selection_info->widget == widget) &&
3059 (selection_info->selection == data->selection))
3061 gulong time = selection_info->time;
3063 gtk_selection_data_set (data,
3064 GDK_SELECTION_TYPE_INTEGER,
3071 tmp_list = tmp_list->next;
3076 else if (data->target == gtk_selection_atoms[TARGETS])
3078 /* List of all targets supported for this widget/selection pair */
3082 GtkTargetList *target_list;
3083 GtkTargetPair *pair;
3085 target_list = gtk_selection_target_list_get (widget,
3087 count = g_list_length (target_list->list) + 3;
3089 data->type = GDK_SELECTION_TYPE_ATOM;
3091 data->length = count * sizeof (GdkAtom);
3093 /* selection data is always terminated by a trailing \0
3095 p = g_malloc (data->length + 1);
3096 data->data = (guchar *)p;
3097 data->data[data->length] = '\0';
3099 *p++ = gtk_selection_atoms[TIMESTAMP];
3100 *p++ = gtk_selection_atoms[TARGETS];
3101 *p++ = gtk_selection_atoms[MULTIPLE];
3103 tmp_list = target_list->list;
3106 pair = (GtkTargetPair *)tmp_list->data;
3107 *p++ = pair->target;
3109 tmp_list = tmp_list->next;
3112 else if (data->target == gtk_selection_atoms[SAVE_TARGETS])
3114 gtk_selection_data_set (data,
3115 gdk_atom_intern_static_string ("NULL"),
3126 * gtk_selection_data_copy:
3127 * @data: a pointer to a #GtkSelectionData structure.
3129 * Makes a copy of a #GtkSelectionData structure and its data.
3131 * Return value: a pointer to a copy of @data.
3134 gtk_selection_data_copy (const GtkSelectionData *data)
3136 GtkSelectionData *new_data;
3138 g_return_val_if_fail (data != NULL, NULL);
3140 new_data = g_slice_new (GtkSelectionData);
3145 new_data->data = g_malloc (data->length + 1);
3146 memcpy (new_data->data, data->data, data->length + 1);
3153 * gtk_selection_data_free:
3154 * @data: a pointer to a #GtkSelectionData structure.
3156 * Frees a #GtkSelectionData structure returned from
3157 * gtk_selection_data_copy().
3160 gtk_selection_data_free (GtkSelectionData *data)
3162 g_return_if_fail (data != NULL);
3164 g_free (data->data);
3166 g_slice_free (GtkSelectionData, data);
3170 * gtk_target_entry_new:
3171 * @target: String identifier for target
3172 * @flags: Set of flags, see #GtkTargetFlags
3173 * @info: an ID that will be passed back to the application
3175 * Makes a new #GtkTargetEntry structure.
3177 * Return value: a pointer to a new GtkTargetEntry structure.
3178 * Free with gtk_target_entry_free()
3181 gtk_target_entry_new (const char *target,
3185 GtkTargetEntry entry = { (char *) target, flags, info };
3186 return gtk_target_entry_copy (&entry);
3190 * gtk_target_entry_copy:
3191 * @data: a pointer to a #GtkTargetEntry structure.
3193 * Makes a copy of a #GtkTargetEntry structure and its data.
3195 * Return value: a pointer to a copy of @data.
3196 * Free with gtk_target_entry_free()
3199 gtk_target_entry_copy (GtkTargetEntry *data)
3201 GtkTargetEntry *new_data;
3203 g_return_val_if_fail (data != NULL, NULL);
3205 new_data = g_slice_new (GtkTargetEntry);
3206 new_data->target = g_strdup (data->target);
3207 new_data->flags = data->flags;
3208 new_data->info = data->info;
3214 * gtk_target_entry_free:
3215 * @data: a pointer to a #GtkTargetEntry structure.
3217 * Frees a #GtkTargetEntry structure returned from
3218 * gtk_target_entry_new() or gtk_target_entry_copy().
3221 gtk_target_entry_free (GtkTargetEntry *data)
3223 g_return_if_fail (data != NULL);
3225 g_free (data->target);
3227 g_slice_free (GtkTargetEntry, data);
3231 G_DEFINE_BOXED_TYPE (GtkSelectionData, gtk_selection_data,
3232 gtk_selection_data_copy,
3233 gtk_selection_data_free)
3235 G_DEFINE_BOXED_TYPE (GtkTargetList, gtk_target_list,
3236 gtk_target_list_ref,
3237 gtk_target_list_unref)
3239 G_DEFINE_BOXED_TYPE (GtkTargetEntry, gtk_target_entry,
3240 gtk_target_entry_copy,
3241 gtk_target_entry_free)
3244 gtk_selection_bytes_per_item (gint format)
3249 return sizeof (char);
3252 return sizeof (short);
3255 return sizeof (long);
3258 g_assert_not_reached();