]> Pileus Git - ~andy/gtk/blob - gtk/gtkclipboard.c
range: don't draw origin when the slider is invisible
[~andy/gtk] / gtk / gtkclipboard.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2000 Red Hat, Inc.
3  * Copyright (C) 2004 Nokia Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * Global clipboard abstraction. 
19  */
20
21 #include "config.h"
22 #include <string.h>
23
24 #include "gtkclipboard.h"
25 #include "gtkinvisible.h"
26 #include "gtkmain.h"
27 #include "gtkmarshalers.h"
28 #include "gtktextbufferrichtext.h"
29 #include "gtkintl.h"
30
31 #ifdef GDK_WINDOWING_X11
32 #include "x11/gdkx.h"
33 #endif
34
35 #ifdef GDK_WINDOWING_BROADWAY
36 #include "broadway/gdkbroadway.h"
37 #endif
38
39 #ifdef GDK_WINDOWING_WIN32
40 #include "win32/gdkwin32.h"
41 #endif
42
43
44 /**
45  * SECTION:gtkclipboard
46  * @Short_description: Storing data on clipboards
47  * @Title: Clipboards
48  * @See_also: #GtkSelection
49  *
50  * The #GtkClipboard object represents a clipboard of data shared
51  * between different processes or between different widgets in
52  * the same process. Each clipboard is identified by a name encoded as a
53  * #GdkAtom. (Conversion to and from strings can be done with
54  * gdk_atom_intern() and gdk_atom_name().) The default clipboard
55  * corresponds to the "CLIPBOARD" atom; another commonly used clipboard
56  * is the "PRIMARY" clipboard, which, in X, traditionally contains
57  * the currently selected text.
58  *
59  * To support having a number of different formats on the clipboard
60  * at the same time, the clipboard mechanism allows providing
61  * callbacks instead of the actual data.  When you set the contents
62  * of the clipboard, you can either supply the data directly (via
63  * functions like gtk_clipboard_set_text()), or you can supply a
64  * callback to be called at a later time when the data is needed (via
65  * gtk_clipboard_set_with_data() or gtk_clipboard_set_with_owner().)
66  * Providing a callback also avoids having to make copies of the data
67  * when it is not needed.
68  *
69  * gtk_clipboard_set_with_data() and gtk_clipboard_set_with_owner()
70  * are quite similar; the choice between the two depends mostly on
71  * which is more convenient in a particular situation.
72  * The former is most useful when you want to have a blob of data
73  * with callbacks to convert it into the various data types that you
74  * advertise. When the @clear_func you provided is called, you
75  * simply free the data blob. The latter is more useful when the
76  * contents of clipboard reflect the internal state of a #GObject
77  * (As an example, for the PRIMARY clipboard, when an entry widget
78  * provides the clipboard's contents the contents are simply the
79  * text within the selected region.) If the contents change, the
80  * entry widget can call gtk_clipboard_set_with_owner() to update
81  * the timestamp for clipboard ownership, without having to worry
82  * about @clear_func being called.
83  *
84  * Requesting the data from the clipboard is essentially
85  * asynchronous. If the contents of the clipboard are provided within
86  * the same process, then a direct function call will be made to
87  * retrieve the data, but if they are provided by another process,
88  * then the data needs to be retrieved from the other process, which
89  * may take some time. To avoid blocking the user interface, the call
90  * to request the selection, gtk_clipboard_request_contents() takes a
91  * callback that will be called when the contents are received (or
92  * when the request fails.) If you don't want to deal with providing
93  * a separate callback, you can also use gtk_clipboard_wait_for_contents().
94  * What this does is run the GLib main loop recursively waiting for
95  * the contents. This can simplify the code flow, but you still have
96  * to be aware that other callbacks in your program can be called
97  * while this recursive mainloop is running.
98  *
99  * Along with the functions to get the clipboard contents as an
100  * arbitrary data chunk, there are also functions to retrieve
101  * it as text, gtk_clipboard_request_text() and
102  * gtk_clipboard_wait_for_text(). These functions take care of
103  * determining which formats are advertised by the clipboard
104  * provider, asking for the clipboard in the best available format
105  * and converting the results into the UTF-8 encoding. (The standard
106  * form for representing strings in GTK+.)
107  */
108
109
110 enum {
111   OWNER_CHANGE,
112   LAST_SIGNAL
113 };
114
115 typedef struct _GtkClipboardClass GtkClipboardClass;
116
117 typedef struct _RequestContentsInfo RequestContentsInfo;
118 typedef struct _RequestTextInfo RequestTextInfo;
119 typedef struct _RequestRichTextInfo RequestRichTextInfo;
120 typedef struct _RequestImageInfo RequestImageInfo;
121 typedef struct _RequestURIInfo RequestURIInfo;
122 typedef struct _RequestTargetsInfo RequestTargetsInfo;
123
124 struct _GtkClipboard 
125 {
126   GObject parent_instance;
127
128   GdkAtom selection;
129
130   GtkClipboardGetFunc get_func;
131   GtkClipboardClearFunc clear_func;
132   gpointer user_data;
133   gboolean have_owner;
134
135   guint32 timestamp;
136
137   gboolean have_selection;
138   GdkDisplay *display;
139
140   GdkAtom *cached_targets;
141   gint     n_cached_targets;
142
143   gulong     notify_signal_id;
144   gboolean   storing_selection;
145   GMainLoop *store_loop;
146   guint      store_timeout;
147   gint       n_storable_targets;
148   GdkAtom   *storable_targets;
149 };
150
151 struct _GtkClipboardClass
152 {
153   GObjectClass parent_class;
154
155   void (*owner_change) (GtkClipboard        *clipboard,
156                         GdkEventOwnerChange *event);
157 };
158
159 struct _RequestContentsInfo
160 {
161   GtkClipboardReceivedFunc callback;
162   gpointer user_data;
163 };
164
165 struct _RequestTextInfo
166 {
167   GtkClipboardTextReceivedFunc callback;
168   gpointer user_data;
169 };
170
171 struct _RequestRichTextInfo
172 {
173   GtkClipboardRichTextReceivedFunc callback;
174   GdkAtom *atoms;
175   gint     n_atoms;
176   gint     current_atom;
177   gpointer user_data;
178 };
179
180 struct _RequestImageInfo
181 {
182   GtkClipboardImageReceivedFunc callback;
183   gpointer user_data;
184 };
185
186 struct _RequestURIInfo
187 {
188   GtkClipboardURIReceivedFunc callback;
189   gpointer user_data;
190 };
191
192 struct _RequestTargetsInfo
193 {
194   GtkClipboardTargetsReceivedFunc callback;
195   gpointer user_data;
196 };
197
198 static void gtk_clipboard_class_init   (GtkClipboardClass   *class);
199 static void gtk_clipboard_finalize     (GObject             *object);
200 static void gtk_clipboard_owner_change (GtkClipboard        *clipboard,
201                                         GdkEventOwnerChange *event);
202
203 static void          clipboard_unset      (GtkClipboard     *clipboard);
204 static void          selection_received   (GtkWidget        *widget,
205                                            GtkSelectionData *selection_data,
206                                            guint             time);
207 static GtkClipboard *clipboard_peek       (GdkDisplay       *display,
208                                            GdkAtom           selection,
209                                            gboolean          only_if_exists);
210 static GtkWidget *   get_clipboard_widget (GdkDisplay       *display);
211
212
213 enum {
214   TARGET_STRING,
215   TARGET_TEXT,
216   TARGET_COMPOUND_TEXT,
217   TARGET_UTF8_STRING,
218   TARGET_SAVE_TARGETS
219 };
220
221 static const gchar request_contents_key[] = "gtk-request-contents";
222 static GQuark request_contents_key_id = 0;
223
224 static const gchar clipboards_owned_key[] = "gtk-clipboards-owned";
225 static GQuark clipboards_owned_key_id = 0;
226
227 static guint         clipboard_signals[LAST_SIGNAL] = { 0 };
228
229 G_DEFINE_TYPE (GtkClipboard, gtk_clipboard, G_TYPE_OBJECT)
230
231 static void
232 gtk_clipboard_init (GtkClipboard *object)
233 {
234 }
235
236 static void
237 gtk_clipboard_class_init (GtkClipboardClass *class)
238 {
239   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
240
241   gobject_class->finalize = gtk_clipboard_finalize;
242
243   class->owner_change = gtk_clipboard_owner_change;
244
245   /**
246    * GtkClipboard::owner-change:
247    * @clipboard: the #GtkClipboard on which the signal is emitted
248    * @event: (type Gdk.EventOwnerChange): the @GdkEventOwnerChange event
249    *
250    * The ::owner-change signal is emitted when GTK+ receives an
251    * event that indicates that the ownership of the selection
252    * associated with @clipboard has changed.
253    *
254    * Since: 2.6
255    */
256   clipboard_signals[OWNER_CHANGE] =
257     g_signal_new (I_("owner-change"),
258                   G_TYPE_FROM_CLASS (gobject_class),
259                   G_SIGNAL_RUN_FIRST,
260                   G_STRUCT_OFFSET (GtkClipboardClass, owner_change),
261                   NULL, NULL,
262                   _gtk_marshal_VOID__BOXED,
263                   G_TYPE_NONE, 1,
264                   GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
265 }
266
267 static void
268 gtk_clipboard_finalize (GObject *object)
269 {
270   GtkClipboard *clipboard;
271   GtkWidget *clipboard_widget = NULL;
272   GSList *clipboards = NULL;
273
274   clipboard = GTK_CLIPBOARD (object);
275
276   if (clipboard->display)
277     {
278       clipboards = g_object_get_data (G_OBJECT (clipboard->display), "gtk-clipboard-list");
279
280       if (g_slist_index (clipboards, clipboard) >= 0)
281         g_warning ("GtkClipboard prematurely finalized");
282
283       clipboards = g_slist_remove (clipboards, clipboard);
284
285       g_object_set_data (G_OBJECT (clipboard->display), "gtk-clipboard-list", 
286                          clipboards);
287
288       /* don't use get_clipboard_widget() here because it would create the
289        * widget if it doesn't exist.
290        */
291       clipboard_widget = g_object_get_data (G_OBJECT (clipboard->display),
292                                             "gtk-clipboard-widget");
293     }
294
295   clipboard_unset (clipboard);
296
297   if (clipboard->store_loop && g_main_loop_is_running (clipboard->store_loop))
298     g_main_loop_quit (clipboard->store_loop);
299
300   if (clipboard->store_timeout != 0)
301     g_source_remove (clipboard->store_timeout);
302
303   if (clipboard->notify_signal_id != 0)
304     g_signal_handler_disconnect (clipboard_widget, clipboard->notify_signal_id);
305
306   g_free (clipboard->storable_targets);
307   g_free (clipboard->cached_targets);
308
309   G_OBJECT_CLASS (gtk_clipboard_parent_class)->finalize (object);
310 }
311
312 static void
313 clipboard_display_closed (GdkDisplay   *display,
314                           gboolean      is_error,
315                           GtkClipboard *clipboard)
316 {
317   GSList *clipboards;
318
319   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
320   g_object_run_dispose (G_OBJECT (clipboard));
321   clipboards = g_slist_remove (clipboards, clipboard);
322   g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
323   g_object_unref (clipboard);
324 }
325
326 /**
327  * gtk_clipboard_get_for_display:
328  * @display: the display for which the clipboard is to be retrieved or created
329  * @selection: a #GdkAtom which identifies the clipboard to use.
330  *
331  * Returns the clipboard object for the given selection.
332  * Cut/copy/paste menu items and keyboard shortcuts should use
333  * the default clipboard, returned by passing %GDK_SELECTION_CLIPBOARD for @selection.
334  * (%GDK_NONE is supported as a synonym for GDK_SELECTION_CLIPBOARD
335  * for backwards compatibility reasons.)
336  * The currently-selected object or text should be provided on the clipboard
337  * identified by #GDK_SELECTION_PRIMARY. Cut/copy/paste menu items
338  * conceptually copy the contents of the #GDK_SELECTION_PRIMARY clipboard
339  * to the default clipboard, i.e. they copy the selection to what the
340  * user sees as the clipboard.
341  *
342  * (Passing #GDK_NONE is the same as using <literal>gdk_atom_intern
343  * ("CLIPBOARD", FALSE)</literal>. See <ulink
344  * url="http://www.freedesktop.org/Standards/clipboards-spec">
345  * http://www.freedesktop.org/Standards/clipboards-spec</ulink>
346  * for a detailed discussion of the "CLIPBOARD" vs. "PRIMARY"
347  * selections under the X window system. On Win32 the
348  * #GDK_SELECTION_PRIMARY clipboard is essentially ignored.)
349  *
350  * It's possible to have arbitrary named clipboards; if you do invent
351  * new clipboards, you should prefix the selection name with an
352  * underscore (because the ICCCM requires that nonstandard atoms are
353  * underscore-prefixed), and namespace it as well. For example,
354  * if your application called "Foo" has a special-purpose
355  * clipboard, you might call it "_FOO_SPECIAL_CLIPBOARD".
356  *
357  * Return value: (transfer none): the appropriate clipboard object. If no
358  *   clipboard already exists, a new one will be created. Once a clipboard
359  *   object has been created, it is persistent and, since it is owned by
360  *   GTK+, must not be freed or unrefd.
361  *
362  * Since: 2.2
363  **/
364 GtkClipboard *
365 gtk_clipboard_get_for_display (GdkDisplay *display, 
366                                GdkAtom     selection)
367 {
368   g_return_val_if_fail (display != NULL, NULL); /* See bgo#463773; this is needed because Flash Player sucks */
369   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
370   g_return_val_if_fail (!gdk_display_is_closed (display), NULL);
371
372   return clipboard_peek (display, selection, FALSE);
373 }
374
375
376 /**
377  * gtk_clipboard_get:
378  * @selection: a #GdkAtom which identifies the clipboard to use
379  *
380  * Returns the clipboard object for the given selection.
381  * See gtk_clipboard_get_for_display() for complete details.
382  *
383  * Return value: (transfer none): the appropriate clipboard object. If no clipboard
384  *     already exists, a new one will be created. Once a clipboard
385  *     object has been created, it is persistent and, since it is
386  *     owned by GTK+, must not be freed or unreffed.
387  */
388 GtkClipboard *
389 gtk_clipboard_get (GdkAtom selection)
390 {
391   return gtk_clipboard_get_for_display (gdk_display_get_default (), selection);
392 }
393
394 static void 
395 selection_get_cb (GtkWidget          *widget,
396                   GtkSelectionData   *selection_data,
397                   guint               info,
398                   guint               time)
399 {
400   GtkClipboard *clipboard;
401
402   clipboard = gtk_widget_get_clipboard (widget,
403                                         gtk_selection_data_get_selection (selection_data));
404
405   if (clipboard && clipboard->get_func)
406     clipboard->get_func (clipboard, selection_data, info, clipboard->user_data);
407 }
408
409 static gboolean
410 selection_clear_event_cb (GtkWidget         *widget,
411                           GdkEventSelection *event)
412 {
413   GtkClipboard *clipboard = gtk_widget_get_clipboard (widget, event->selection);
414
415   if (clipboard)
416     {
417       clipboard_unset (clipboard);
418
419       return TRUE;
420     }
421
422   return FALSE;
423 }
424
425 static GtkWidget *
426 make_clipboard_widget (GdkDisplay *display, 
427                        gboolean    provider)
428 {
429   GtkWidget *widget = gtk_invisible_new_for_screen (gdk_display_get_default_screen (display));
430
431   g_signal_connect (widget, "selection-received",
432                     G_CALLBACK (selection_received), NULL);
433
434   if (provider)
435     {
436       /* We need this for gdk_x11_get_server_time() */
437       gtk_widget_add_events (widget, GDK_PROPERTY_CHANGE_MASK);
438       
439       g_signal_connect (widget, "selection-get",
440                         G_CALLBACK (selection_get_cb), NULL);
441       g_signal_connect (widget, "selection-clear-event",
442                         G_CALLBACK (selection_clear_event_cb), NULL);
443     }
444
445   return widget;
446 }
447
448 static GtkWidget *
449 get_clipboard_widget (GdkDisplay *display)
450 {
451   GtkWidget *clip_widget = g_object_get_data (G_OBJECT (display), "gtk-clipboard-widget");
452   if (!clip_widget)
453     {
454       clip_widget = make_clipboard_widget (display, TRUE);
455       g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-widget"), clip_widget);
456     }
457
458   return clip_widget;
459 }
460
461 /* This function makes a very good guess at what the correct
462  * timestamp for a selection request should be. If there is
463  * a currently processed event, it uses the timestamp for that
464  * event, otherwise it uses the current server time. However,
465  * if the time resulting from that is older than the time used
466  * last time, it uses the time used last time instead.
467  *
468  * In order implement this correctly, we never use CurrentTime,
469  * but actually retrieve the actual timestamp from the server.
470  * This is a little slower but allows us to make the guarantee
471  * that the times used by this application will always ascend
472  * and we won't get selections being rejected just because
473  * we are using a correct timestamp from an event, but used
474  * CurrentTime previously.
475  */
476 static guint32
477 clipboard_get_timestamp (GtkClipboard *clipboard)
478 {
479   GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display);
480   guint32 timestamp = gtk_get_current_event_time ();
481   GdkWindow *window;
482
483   if (timestamp == GDK_CURRENT_TIME)
484     {
485       window = gtk_widget_get_window (clipboard_widget);
486 #ifdef GDK_WINDOWING_X11
487       if (GDK_IS_X11_WINDOW (window))
488         {
489           timestamp = gdk_x11_get_server_time (gtk_widget_get_window (clipboard_widget));
490         }
491       else
492 #endif
493 #if defined GDK_WINDOWING_WIN32
494       if (GDK_IS_WIN32_WINDOW (window))
495         {
496           timestamp = GetMessageTime ();
497         }
498       else
499 #endif
500 #if defined GDK_WINDOWING_BROADWAY
501       if (GDK_IS_BROADWAY_WINDOW (window))
502         {
503           timestamp = gdk_broadway_get_last_seen_time (window);
504         }
505       else
506 #endif
507         {
508           /* No implementation */
509         }
510     }
511   else
512     {
513       if (clipboard->timestamp != GDK_CURRENT_TIME)
514         {
515           /* Check to see if clipboard->timestamp is newer than
516            * timestamp, accounting for wraparound.
517            */
518
519           guint32 max = timestamp + 0x80000000;
520
521           if ((max > timestamp &&
522                (clipboard->timestamp > timestamp &&
523                 clipboard->timestamp <= max)) ||
524               (max <= timestamp &&
525                (clipboard->timestamp > timestamp ||
526                 clipboard->timestamp <= max)))
527             {
528               timestamp = clipboard->timestamp;
529             }
530         }
531     }
532
533   clipboard->timestamp = timestamp;
534
535   return timestamp;
536 }
537
538 static void
539 clipboard_owner_destroyed (gpointer data)
540 {
541   GSList *clipboards = data;
542   GSList *tmp_list;
543
544   tmp_list = clipboards;
545   while (tmp_list)
546     {
547       GtkClipboard *clipboard = tmp_list->data;
548
549       clipboard->get_func = NULL;
550       clipboard->clear_func = NULL;
551       clipboard->user_data = NULL;
552       clipboard->have_owner = FALSE;
553
554       gtk_clipboard_clear (clipboard);
555
556       tmp_list = tmp_list->next;
557     }
558   
559   g_slist_free (clipboards);
560 }
561
562 static void
563 clipboard_add_owner_notify (GtkClipboard *clipboard)
564 {
565   if (!clipboards_owned_key_id)
566     clipboards_owned_key_id = g_quark_from_static_string (clipboards_owned_key);
567   
568   if (clipboard->have_owner)
569     g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
570                              g_slist_prepend (g_object_steal_qdata (clipboard->user_data,
571                                                                     clipboards_owned_key_id),
572                                               clipboard),
573                              clipboard_owner_destroyed);
574 }
575
576 static void
577 clipboard_remove_owner_notify (GtkClipboard *clipboard)
578 {
579   if (clipboard->have_owner)
580      g_object_set_qdata_full (clipboard->user_data, clipboards_owned_key_id,
581                               g_slist_remove (g_object_steal_qdata (clipboard->user_data,
582                                                                     clipboards_owned_key_id),
583                                               clipboard),
584                               clipboard_owner_destroyed);
585 }
586           
587 static gboolean
588 gtk_clipboard_set_contents (GtkClipboard         *clipboard,
589                             const GtkTargetEntry *targets,
590                             guint                 n_targets,
591                             GtkClipboardGetFunc   get_func,
592                             GtkClipboardClearFunc clear_func,
593                             gpointer              user_data,
594                             gboolean              have_owner)
595 {
596   GtkWidget *clipboard_widget = get_clipboard_widget (clipboard->display);
597
598   if (gtk_selection_owner_set_for_display (clipboard->display,
599                                            clipboard_widget,
600                                            clipboard->selection,
601                                            clipboard_get_timestamp (clipboard)))
602     {
603       clipboard->have_selection = TRUE;
604
605       if (clipboard->n_cached_targets != -1)
606         {
607           g_free (clipboard->cached_targets);
608           clipboard->cached_targets = NULL;
609           clipboard->n_cached_targets = -1;
610         }
611
612       if (!(clipboard->have_owner && have_owner) ||
613           clipboard->user_data != user_data)
614         {
615           clipboard_unset (clipboard);
616
617           if (clipboard->get_func)
618             {
619               /* Calling unset() caused the clipboard contents to be reset!
620                * Avoid leaking and return 
621                */
622               if (!(clipboard->have_owner && have_owner) ||
623                   clipboard->user_data != user_data)
624                 {
625                   (*clear_func) (clipboard, user_data);
626                   return FALSE;
627                 }
628               else
629                 return TRUE;
630             }
631           else
632             {
633               clipboard->user_data = user_data;
634               clipboard->have_owner = have_owner;
635               if (have_owner)
636                 clipboard_add_owner_notify (clipboard);
637             }
638           
639         }
640
641       clipboard->get_func = get_func;
642       clipboard->clear_func = clear_func;
643
644       gtk_selection_clear_targets (clipboard_widget, clipboard->selection);
645       gtk_selection_add_targets (clipboard_widget, clipboard->selection,
646                                  targets, n_targets);
647
648       return TRUE;
649     }
650   else
651     return FALSE;
652 }
653
654 /**
655  * gtk_clipboard_set_with_data: (skip)
656  * @clipboard: a #GtkClipboard
657  * @targets: (array length=n_targets): array containing information
658  *     about the available forms for the clipboard data
659  * @n_targets: number of elements in @targets
660  * @get_func: (scope async): function to call to get the actual clipboard data
661  * @clear_func: (scope async): when the clipboard contents are set again,
662  *     this function will be called, and @get_func will not be subsequently
663  *     called.
664  * @user_data: user data to pass to @get_func and @clear_func.
665  *
666  * Virtually sets the contents of the specified clipboard by providing
667  * a list of supported formats for the clipboard data and a function
668  * to call to get the actual data when it is requested.
669  *
670  * Return value: %TRUE if setting the clipboard data succeeded.
671  *    If setting the clipboard data failed the provided callback
672  *    functions will be ignored.
673  **/
674 gboolean
675 gtk_clipboard_set_with_data (GtkClipboard          *clipboard,
676                              const GtkTargetEntry  *targets,
677                              guint                  n_targets,
678                              GtkClipboardGetFunc    get_func,
679                              GtkClipboardClearFunc  clear_func,
680                              gpointer               user_data)
681 {
682   g_return_val_if_fail (clipboard != NULL, FALSE);
683   g_return_val_if_fail (targets != NULL, FALSE);
684   g_return_val_if_fail (get_func != NULL, FALSE);
685
686   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
687                                      get_func, clear_func, user_data,
688                                      FALSE);
689 }
690
691 /**
692  * gtk_clipboard_set_with_owner: (skip)
693  * @clipboard: a #GtkClipboard
694  * @targets: (array length=n_targets): array containing information
695  *     about the available forms for the clipboard data
696  * @n_targets: number of elements in @targets
697  * @get_func: (scope async): function to call to get the actual clipboard data
698  * @clear_func: (scope async): when the clipboard contents are set again,
699  *     this function will be called, and @get_func will not be subsequently
700  *     called
701  * @owner: an object that "owns" the data. This object will be passed
702  *     to the callbacks when called
703  *
704  * Virtually sets the contents of the specified clipboard by providing
705  * a list of supported formats for the clipboard data and a function
706  * to call to get the actual data when it is requested.
707  *
708  * The difference between this function and gtk_clipboard_set_with_data()
709  * is that instead of an generic @user_data pointer, a #GObject is passed
710  * in.
711  *
712  * Return value: %TRUE if setting the clipboard data succeeded.
713  *     If setting the clipboard data failed the provided callback
714  *     functions will be ignored.
715  **/
716 gboolean
717 gtk_clipboard_set_with_owner (GtkClipboard          *clipboard,
718                               const GtkTargetEntry  *targets,
719                               guint                  n_targets,
720                               GtkClipboardGetFunc    get_func,
721                               GtkClipboardClearFunc  clear_func,
722                               GObject               *owner)
723 {
724   g_return_val_if_fail (clipboard != NULL, FALSE);
725   g_return_val_if_fail (targets != NULL, FALSE);
726   g_return_val_if_fail (get_func != NULL, FALSE);
727   g_return_val_if_fail (G_IS_OBJECT (owner), FALSE);
728
729   return gtk_clipboard_set_contents (clipboard, targets, n_targets,
730                                      get_func, clear_func, owner,
731                                      TRUE);
732 }
733
734 /**
735  * gtk_clipboard_get_owner:
736  * @clipboard: a #GtkClipboard
737  *
738  * If the clipboard contents callbacks were set with
739  * gtk_clipboard_set_with_owner(), and the gtk_clipboard_set_with_data() or
740  * gtk_clipboard_clear() has not subsequently called, returns the owner set
741  * by gtk_clipboard_set_with_owner().
742  *
743  * Return value: (transfer none): the owner of the clipboard, if any;
744  *     otherwise %NULL.
745  **/
746 GObject *
747 gtk_clipboard_get_owner (GtkClipboard *clipboard)
748 {
749   g_return_val_if_fail (clipboard != NULL, NULL);
750
751   if (clipboard->have_owner)
752     return clipboard->user_data;
753   else
754     return NULL;
755 }
756
757 static void
758 clipboard_unset (GtkClipboard *clipboard)
759 {
760   GtkClipboardClearFunc old_clear_func;
761   gpointer old_data;
762   gboolean old_have_owner;
763   gint old_n_storable_targets;
764   
765   old_clear_func = clipboard->clear_func;
766   old_data = clipboard->user_data;
767   old_have_owner = clipboard->have_owner;
768   old_n_storable_targets = clipboard->n_storable_targets;
769   
770   if (old_have_owner)
771     {
772       clipboard_remove_owner_notify (clipboard);
773       clipboard->have_owner = FALSE;
774     }
775
776   clipboard->n_storable_targets = -1;
777   g_free (clipboard->storable_targets);
778   clipboard->storable_targets = NULL;
779       
780   clipboard->get_func = NULL;
781   clipboard->clear_func = NULL;
782   clipboard->user_data = NULL;
783   
784   if (old_clear_func)
785     old_clear_func (clipboard, old_data);
786
787   /* If we've transferred the clipboard data to the manager,
788    * unref the owner
789    */
790   if (old_have_owner &&
791       old_n_storable_targets != -1)
792     g_object_unref (old_data);
793 }
794
795 /**
796  * gtk_clipboard_clear:
797  * @clipboard:  a #GtkClipboard
798  * 
799  * Clears the contents of the clipboard. Generally this should only
800  * be called between the time you call gtk_clipboard_set_with_owner()
801  * or gtk_clipboard_set_with_data(),
802  * and when the @clear_func you supplied is called. Otherwise, the
803  * clipboard may be owned by someone else.
804  **/
805 void
806 gtk_clipboard_clear (GtkClipboard *clipboard)
807 {
808   g_return_if_fail (clipboard != NULL);
809
810   if (clipboard->have_selection)
811     gtk_selection_owner_set_for_display (clipboard->display, 
812                                          NULL,
813                                          clipboard->selection,
814                                          clipboard_get_timestamp (clipboard));
815 }
816
817 static void 
818 text_get_func (GtkClipboard     *clipboard,
819                GtkSelectionData *selection_data,
820                guint             info,
821                gpointer          data)
822 {
823   gtk_selection_data_set_text (selection_data, data, -1);
824 }
825
826 static void 
827 text_clear_func (GtkClipboard *clipboard,
828                  gpointer      data)
829 {
830   g_free (data);
831 }
832
833
834 /**
835  * gtk_clipboard_set_text:
836  * @clipboard: a #GtkClipboard object
837  * @text:      a UTF-8 string.
838  * @len:       length of @text, in bytes, or -1, in which case
839  *             the length will be determined with <function>strlen()</function>.
840  * 
841  * Sets the contents of the clipboard to the given UTF-8 string. GTK+ will
842  * make a copy of the text and take responsibility for responding
843  * for requests for the text, and for converting the text into
844  * the requested format.
845  **/
846 void 
847 gtk_clipboard_set_text (GtkClipboard *clipboard,
848                         const gchar  *text,
849                         gint          len)
850 {
851   GtkTargetList *list;
852   GtkTargetEntry *targets;
853   gint n_targets;
854
855   g_return_if_fail (clipboard != NULL);
856   g_return_if_fail (text != NULL);
857
858   list = gtk_target_list_new (NULL, 0);
859   gtk_target_list_add_text_targets (list, 0);
860
861   targets = gtk_target_table_new_from_list (list, &n_targets);
862   
863   if (len < 0)
864     len = strlen (text);
865   
866   gtk_clipboard_set_with_data (clipboard, 
867                                targets, n_targets,
868                                text_get_func, text_clear_func,
869                                g_strndup (text, len));
870   gtk_clipboard_set_can_store (clipboard, NULL, 0);
871
872   gtk_target_table_free (targets, n_targets);
873   gtk_target_list_unref (list);
874 }
875
876 static void 
877 pixbuf_get_func (GtkClipboard     *clipboard,
878                  GtkSelectionData *selection_data,
879                  guint             info,
880                  gpointer          data)
881 {
882   gtk_selection_data_set_pixbuf (selection_data, data);
883 }
884
885 static void 
886 pixbuf_clear_func (GtkClipboard *clipboard,
887                    gpointer      data)
888 {
889   g_object_unref (data);
890 }
891
892 /**
893  * gtk_clipboard_set_image:
894  * @clipboard: a #GtkClipboard object
895  * @pixbuf:    a #GdkPixbuf 
896  * 
897  * Sets the contents of the clipboard to the given #GdkPixbuf. 
898  * GTK+ will take responsibility for responding for requests 
899  * for the image, and for converting the image into the 
900  * requested format.
901  * 
902  * Since: 2.6
903  **/
904 void
905 gtk_clipboard_set_image (GtkClipboard *clipboard,
906                           GdkPixbuf    *pixbuf)
907 {
908   GtkTargetList *list;
909   GtkTargetEntry *targets;
910   gint n_targets;
911
912   g_return_if_fail (clipboard != NULL);
913   g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
914
915   list = gtk_target_list_new (NULL, 0);
916   gtk_target_list_add_image_targets (list, 0, TRUE);
917
918   targets = gtk_target_table_new_from_list (list, &n_targets);
919
920   gtk_clipboard_set_with_data (clipboard, 
921                                targets, n_targets,
922                                pixbuf_get_func, pixbuf_clear_func,
923                                g_object_ref (pixbuf));
924   gtk_clipboard_set_can_store (clipboard, NULL, 0);
925
926   gtk_target_table_free (targets, n_targets);
927   gtk_target_list_unref (list);
928 }
929
930 static void
931 set_request_contents_info (GtkWidget           *widget,
932                            RequestContentsInfo *info)
933 {
934   if (!request_contents_key_id)
935     request_contents_key_id = g_quark_from_static_string (request_contents_key);
936
937   g_object_set_qdata (G_OBJECT (widget), request_contents_key_id, info);
938 }
939
940 static RequestContentsInfo *
941 get_request_contents_info (GtkWidget *widget)
942 {
943   if (!request_contents_key_id)
944     return NULL;
945   else
946     return g_object_get_qdata (G_OBJECT (widget), request_contents_key_id);
947 }
948
949 static void 
950 selection_received (GtkWidget            *widget,
951                     GtkSelectionData     *selection_data,
952                     guint                 time)
953 {
954   RequestContentsInfo *request_info = get_request_contents_info (widget);
955   set_request_contents_info (widget, NULL);
956
957   request_info->callback (gtk_widget_get_clipboard (widget, gtk_selection_data_get_selection (selection_data)),
958                           selection_data,
959                           request_info->user_data);
960
961   g_free (request_info);
962
963   if (widget != get_clipboard_widget (gtk_widget_get_display (widget)))
964     gtk_widget_destroy (widget);
965 }
966
967 /**
968  * gtk_clipboard_request_contents:
969  * @clipboard: a #GtkClipboard
970  * @target: an atom representing the form into which the clipboard
971  *     owner should convert the selection.
972  * @callback: (scope async): A function to call when the results are received
973  *     (or the retrieval fails). If the retrieval fails the length field of
974  *     @selection_data will be negative.
975  * @user_data: user data to pass to @callback
976  *
977  * Requests the contents of clipboard as the given target.
978  * When the results of the result are later received the supplied callback
979  * will be called.
980  **/
981 void 
982 gtk_clipboard_request_contents (GtkClipboard            *clipboard,
983                                 GdkAtom                  target,
984                                 GtkClipboardReceivedFunc callback,
985                                 gpointer                 user_data)
986 {
987   RequestContentsInfo *info;
988   GtkWidget *widget;
989   GtkWidget *clipboard_widget;
990
991   g_return_if_fail (clipboard != NULL);
992   g_return_if_fail (target != GDK_NONE);
993   g_return_if_fail (callback != NULL);
994   
995   clipboard_widget = get_clipboard_widget (clipboard->display);
996
997   if (get_request_contents_info (clipboard_widget))
998     widget = make_clipboard_widget (clipboard->display, FALSE);
999   else
1000     widget = clipboard_widget;
1001
1002   info = g_new (RequestContentsInfo, 1);
1003   info->callback = callback;
1004   info->user_data = user_data;
1005
1006   set_request_contents_info (widget, info);
1007
1008   gtk_selection_convert (widget, clipboard->selection, target,
1009                          clipboard_get_timestamp (clipboard));
1010 }
1011
1012 static void 
1013 request_text_received_func (GtkClipboard     *clipboard,
1014                             GtkSelectionData *selection_data,
1015                             gpointer          data)
1016 {
1017   RequestTextInfo *info = data;
1018   gchar *result = NULL;
1019
1020   result = (gchar *) gtk_selection_data_get_text (selection_data);
1021
1022   if (!result)
1023     {
1024       /* If we asked for UTF8 and didn't get it, try compound_text;
1025        * if we asked for compound_text and didn't get it, try string;
1026        * If we asked for anything else and didn't get it, give up.
1027        */
1028       GdkAtom target = gtk_selection_data_get_target (selection_data);
1029
1030       if (target == gdk_atom_intern_static_string ("UTF8_STRING"))
1031         {
1032           gtk_clipboard_request_contents (clipboard,
1033                                           gdk_atom_intern_static_string ("COMPOUND_TEXT"), 
1034                                           request_text_received_func, info);
1035           return;
1036         }
1037       else if (target == gdk_atom_intern_static_string ("COMPOUND_TEXT"))
1038         {
1039           gtk_clipboard_request_contents (clipboard,
1040                                           GDK_TARGET_STRING, 
1041                                           request_text_received_func, info);
1042           return;
1043         }
1044     }
1045
1046   info->callback (clipboard, result, info->user_data);
1047   g_free (info);
1048   g_free (result);
1049 }
1050
1051 /**
1052  * gtk_clipboard_request_text:
1053  * @clipboard: a #GtkClipboard
1054  * @callback: (scope async): a function to call when the text is received,
1055  *     or the retrieval fails. (It will always be called one way or the other.)
1056  * @user_data: user data to pass to @callback.
1057  *
1058  * Requests the contents of the clipboard as text. When the text is
1059  * later received, it will be converted to UTF-8 if necessary, and
1060  * @callback will be called.
1061  *
1062  * The @text parameter to @callback will contain the resulting text if
1063  * the request succeeded, or %NULL if it failed. This could happen for
1064  * various reasons, in particular if the clipboard was empty or if the
1065  * contents of the clipboard could not be converted into text form.
1066  **/
1067 void 
1068 gtk_clipboard_request_text (GtkClipboard                *clipboard,
1069                             GtkClipboardTextReceivedFunc callback,
1070                             gpointer                     user_data)
1071 {
1072   RequestTextInfo *info;
1073   
1074   g_return_if_fail (clipboard != NULL);
1075   g_return_if_fail (callback != NULL);
1076   
1077   info = g_new (RequestTextInfo, 1);
1078   info->callback = callback;
1079   info->user_data = user_data;
1080
1081   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("UTF8_STRING"),
1082                                   request_text_received_func,
1083                                   info);
1084 }
1085
1086 static void
1087 request_rich_text_received_func (GtkClipboard     *clipboard,
1088                                  GtkSelectionData *selection_data,
1089                                  gpointer          data)
1090 {
1091   RequestRichTextInfo *info = data;
1092   guint8 *result = NULL;
1093   gsize length = 0;
1094
1095   result = (guint8 *) gtk_selection_data_get_data (selection_data);
1096   length = gtk_selection_data_get_length (selection_data);
1097
1098   info->current_atom++;
1099
1100   if ((!result || length < 1) && (info->current_atom < info->n_atoms))
1101     {
1102       gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
1103                                       request_rich_text_received_func,
1104                                       info);
1105       return;
1106     }
1107
1108   info->callback (clipboard, gtk_selection_data_get_target (selection_data),
1109                   result, length,
1110                   info->user_data);
1111   g_free (info->atoms);
1112   g_free (info);
1113 }
1114
1115 /**
1116  * gtk_clipboard_request_rich_text:
1117  * @clipboard: a #GtkClipboard
1118  * @buffer: a #GtkTextBuffer
1119  * @callback: (scope async): a function to call when the text is received,
1120  *     or the retrieval fails. (It will always be called one way or the other.)
1121  * @user_data: user data to pass to @callback.
1122  *
1123  * Requests the contents of the clipboard as rich text. When the rich
1124  * text is later received, @callback will be called.
1125  *
1126  * The @text parameter to @callback will contain the resulting rich
1127  * text if the request succeeded, or %NULL if it failed. The @length
1128  * parameter will contain @text's length. This function can fail for
1129  * various reasons, in particular if the clipboard was empty or if the
1130  * contents of the clipboard could not be converted into rich text form.
1131  *
1132  * Since: 2.10
1133  **/
1134 void
1135 gtk_clipboard_request_rich_text (GtkClipboard                    *clipboard,
1136                                  GtkTextBuffer                   *buffer,
1137                                  GtkClipboardRichTextReceivedFunc callback,
1138                                  gpointer                         user_data)
1139 {
1140   RequestRichTextInfo *info;
1141
1142   g_return_if_fail (clipboard != NULL);
1143   g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
1144   g_return_if_fail (callback != NULL);
1145
1146   info = g_new (RequestRichTextInfo, 1);
1147   info->callback = callback;
1148   info->atoms = NULL;
1149   info->n_atoms = 0;
1150   info->current_atom = 0;
1151   info->user_data = user_data;
1152
1153   info->atoms = gtk_text_buffer_get_deserialize_formats (buffer, &info->n_atoms);
1154
1155   gtk_clipboard_request_contents (clipboard, info->atoms[info->current_atom],
1156                                   request_rich_text_received_func,
1157                                   info);
1158 }
1159
1160 static void 
1161 request_image_received_func (GtkClipboard     *clipboard,
1162                              GtkSelectionData *selection_data,
1163                              gpointer          data)
1164 {
1165   RequestImageInfo *info = data;
1166   GdkPixbuf *result = NULL;
1167
1168   result = gtk_selection_data_get_pixbuf (selection_data);
1169
1170   if (!result)
1171     {
1172       /* If we asked for image/png and didn't get it, try image/jpeg;
1173        * if we asked for image/jpeg and didn't get it, try image/gif;
1174        * if we asked for image/gif and didn't get it, try image/bmp;
1175        * If we asked for anything else and didn't get it, give up.
1176        */
1177       GdkAtom target = gtk_selection_data_get_target (selection_data);
1178
1179       if (target == gdk_atom_intern_static_string ("image/png"))
1180         {
1181           gtk_clipboard_request_contents (clipboard,
1182                                           gdk_atom_intern_static_string ("image/jpeg"), 
1183                                           request_image_received_func, info);
1184           return;
1185         }
1186       else if (target == gdk_atom_intern_static_string ("image/jpeg"))
1187         {
1188           gtk_clipboard_request_contents (clipboard,
1189                                           gdk_atom_intern_static_string ("image/gif"), 
1190                                           request_image_received_func, info);
1191           return;
1192         }
1193       else if (target == gdk_atom_intern_static_string ("image/gif"))
1194         {
1195           gtk_clipboard_request_contents (clipboard,
1196                                           gdk_atom_intern_static_string ("image/bmp"), 
1197                                           request_image_received_func, info);
1198           return;
1199         }
1200     }
1201
1202   info->callback (clipboard, result, info->user_data);
1203   g_free (info);
1204
1205   if (result)
1206     g_object_unref (result);
1207 }
1208
1209 /**
1210  * gtk_clipboard_request_image:
1211  * @clipboard: a #GtkClipboard
1212  * @callback: (scope async): a function to call when the image is received,
1213  *     or the retrieval fails. (It will always be called one way or the other.)
1214  * @user_data: user data to pass to @callback.
1215  *
1216  * Requests the contents of the clipboard as image. When the image is
1217  * later received, it will be converted to a #GdkPixbuf, and
1218  * @callback will be called.
1219  *
1220  * The @pixbuf parameter to @callback will contain the resulting
1221  * #GdkPixbuf if the request succeeded, or %NULL if it failed. This
1222  * could happen for various reasons, in particular if the clipboard
1223  * was empty or if the contents of the clipboard could not be
1224  * converted into an image.
1225  *
1226  * Since: 2.6
1227  **/
1228 void 
1229 gtk_clipboard_request_image (GtkClipboard                  *clipboard,
1230                              GtkClipboardImageReceivedFunc  callback,
1231                              gpointer                       user_data)
1232 {
1233   RequestImageInfo *info;
1234   
1235   g_return_if_fail (clipboard != NULL);
1236   g_return_if_fail (callback != NULL);
1237   
1238   info = g_new (RequestImageInfo, 1);
1239   info->callback = callback;
1240   info->user_data = user_data;
1241
1242   gtk_clipboard_request_contents (clipboard, 
1243                                   gdk_atom_intern_static_string ("image/png"),
1244                                   request_image_received_func,
1245                                   info);
1246 }
1247
1248 static void 
1249 request_uris_received_func (GtkClipboard     *clipboard,
1250                             GtkSelectionData *selection_data,
1251                             gpointer          data)
1252 {
1253   RequestURIInfo *info = data;
1254   gchar **uris;
1255
1256   uris = gtk_selection_data_get_uris (selection_data);
1257   info->callback (clipboard, uris, info->user_data);
1258   g_strfreev (uris);
1259
1260   g_slice_free (RequestURIInfo, info);
1261 }
1262
1263 /**
1264  * gtk_clipboard_request_uris:
1265  * @clipboard: a #GtkClipboard
1266  * @callback: (scope async): a function to call when the URIs are received,
1267  *     or the retrieval fails. (It will always be called one way or the other.)
1268  * @user_data: user data to pass to @callback.
1269  *
1270  * Requests the contents of the clipboard as URIs. When the URIs are
1271  * later received @callback will be called.
1272  *
1273  * The @uris parameter to @callback will contain the resulting array of
1274  * URIs if the request succeeded, or %NULL if it failed. This could happen
1275  * for various reasons, in particular if the clipboard was empty or if the
1276  * contents of the clipboard could not be converted into URI form.
1277  *
1278  * Since: 2.14
1279  **/
1280 void 
1281 gtk_clipboard_request_uris (GtkClipboard                *clipboard,
1282                             GtkClipboardURIReceivedFunc  callback,
1283                             gpointer                     user_data)
1284 {
1285   RequestURIInfo *info;
1286   
1287   g_return_if_fail (clipboard != NULL);
1288   g_return_if_fail (callback != NULL);
1289   
1290   info = g_slice_new (RequestURIInfo);
1291   info->callback = callback;
1292   info->user_data = user_data;
1293
1294   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("text/uri-list"),
1295                                   request_uris_received_func,
1296                                   info);
1297 }
1298
1299 static void 
1300 request_targets_received_func (GtkClipboard     *clipboard,
1301                                GtkSelectionData *selection_data,
1302                                gpointer          data)
1303 {
1304   RequestTargetsInfo *info = data;
1305   GdkAtom *targets = NULL;
1306   gint n_targets = 0;
1307
1308   gtk_selection_data_get_targets (selection_data, &targets, &n_targets);
1309
1310   info->callback (clipboard, targets, n_targets, info->user_data);
1311
1312   g_free (info);
1313   g_free (targets);
1314 }
1315
1316 /**
1317  * gtk_clipboard_request_targets:
1318  * @clipboard: a #GtkClipboard
1319  * @callback: (scope async): a function to call when the targets are
1320  *     received, or the retrieval fails. (It will always be called
1321  *     one way or the other.)
1322  * @user_data: user data to pass to @callback.
1323  *
1324  * Requests the contents of the clipboard as list of supported targets.
1325  * When the list is later received, @callback will be called.
1326  *
1327  * The @targets parameter to @callback will contain the resulting targets if
1328  * the request succeeded, or %NULL if it failed.
1329  *
1330  * Since: 2.4
1331  **/
1332 void 
1333 gtk_clipboard_request_targets (GtkClipboard                *clipboard,
1334                                GtkClipboardTargetsReceivedFunc callback,
1335                                gpointer                     user_data)
1336 {
1337   RequestTargetsInfo *info;
1338   
1339   g_return_if_fail (clipboard != NULL);
1340   g_return_if_fail (callback != NULL);
1341
1342   /* If the display supports change notification we cache targets */
1343   if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)) &&
1344       clipboard->n_cached_targets != -1)
1345     {
1346       (* callback) (clipboard, clipboard->cached_targets, clipboard->n_cached_targets, user_data);
1347       return;
1348     }
1349   
1350   info = g_new (RequestTargetsInfo, 1);
1351   info->callback = callback;
1352   info->user_data = user_data;
1353
1354   gtk_clipboard_request_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"),
1355                                   request_targets_received_func,
1356                                   info);
1357 }
1358
1359 typedef struct
1360 {
1361   GMainLoop *loop;
1362   gpointer data;
1363   GdkAtom format; /* used by rich text */
1364   gsize length; /* used by rich text */
1365 } WaitResults;
1366
1367 static void 
1368 clipboard_received_func (GtkClipboard     *clipboard,
1369                          GtkSelectionData *selection_data,
1370                          gpointer          data)
1371 {
1372   WaitResults *results = data;
1373
1374   if (gtk_selection_data_get_length (selection_data) >= 0)
1375     results->data = gtk_selection_data_copy (selection_data);
1376   
1377   g_main_loop_quit (results->loop);
1378 }
1379
1380 /**
1381  * gtk_clipboard_wait_for_contents:
1382  * @clipboard: a #GtkClipboard
1383  * @target: an atom representing the form into which the clipboard
1384  *          owner should convert the selection.
1385  * 
1386  * Requests the contents of the clipboard using the given target.
1387  * This function waits for the data to be received using the main 
1388  * loop, so events, timeouts, etc, may be dispatched during the wait.
1389  * 
1390  * Return value: a newly-allocated #GtkSelectionData object or %NULL
1391  *               if retrieving the given target failed. If non-%NULL,
1392  *               this value must be freed with gtk_selection_data_free() 
1393  *               when you are finished with it.
1394  **/
1395 GtkSelectionData *
1396 gtk_clipboard_wait_for_contents (GtkClipboard *clipboard,
1397                                  GdkAtom       target)
1398 {
1399   WaitResults results;
1400
1401   g_return_val_if_fail (clipboard != NULL, NULL);
1402   g_return_val_if_fail (target != GDK_NONE, NULL);
1403   
1404   results.data = NULL;
1405   results.loop = g_main_loop_new (NULL, TRUE);
1406
1407   gtk_clipboard_request_contents (clipboard, target, 
1408                                   clipboard_received_func,
1409                                   &results);
1410
1411   if (g_main_loop_is_running (results.loop))
1412     {
1413       gdk_threads_leave ();
1414       g_main_loop_run (results.loop);
1415       gdk_threads_enter ();
1416     }
1417
1418   g_main_loop_unref (results.loop);
1419
1420   return results.data;
1421 }
1422
1423 static void 
1424 clipboard_text_received_func (GtkClipboard *clipboard,
1425                               const gchar  *text,
1426                               gpointer      data)
1427 {
1428   WaitResults *results = data;
1429
1430   results->data = g_strdup (text);
1431   g_main_loop_quit (results->loop);
1432 }
1433
1434 /**
1435  * gtk_clipboard_wait_for_text:
1436  * @clipboard: a #GtkClipboard
1437  * 
1438  * Requests the contents of the clipboard as text and converts
1439  * the result to UTF-8 if necessary. This function waits for
1440  * the data to be received using the main loop, so events,
1441  * timeouts, etc, may be dispatched during the wait.
1442  * 
1443  * Return value: a newly-allocated UTF-8 string which must
1444  *               be freed with g_free(), or %NULL if retrieving
1445  *               the selection data failed. (This could happen
1446  *               for various reasons, in particular if the
1447  *               clipboard was empty or if the contents of the
1448  *               clipboard could not be converted into text form.)
1449  **/
1450 gchar *
1451 gtk_clipboard_wait_for_text (GtkClipboard *clipboard)
1452 {
1453   WaitResults results;
1454
1455   g_return_val_if_fail (clipboard != NULL, NULL);
1456   
1457   results.data = NULL;
1458   results.loop = g_main_loop_new (NULL, TRUE);
1459
1460   gtk_clipboard_request_text (clipboard,
1461                               clipboard_text_received_func,
1462                               &results);
1463
1464   if (g_main_loop_is_running (results.loop))
1465     {
1466       gdk_threads_leave ();
1467       g_main_loop_run (results.loop);
1468       gdk_threads_enter ();
1469     }
1470
1471   g_main_loop_unref (results.loop);
1472
1473   return results.data;
1474 }
1475
1476 static void
1477 clipboard_rich_text_received_func (GtkClipboard *clipboard,
1478                                    GdkAtom       format,
1479                                    const guint8 *text,
1480                                    gsize         length,
1481                                    gpointer      data)
1482 {
1483   WaitResults *results = data;
1484
1485   results->data = g_memdup (text, length);
1486   results->format = format;
1487   results->length = length;
1488   g_main_loop_quit (results->loop);
1489 }
1490
1491 /**
1492  * gtk_clipboard_wait_for_rich_text:
1493  * @clipboard: a #GtkClipboard
1494  * @buffer: a #GtkTextBuffer
1495  * @format: (out): return location for the format of the returned data
1496  * @length: return location for the length of the returned data
1497  *
1498  * Requests the contents of the clipboard as rich text.  This function
1499  * waits for the data to be received using the main loop, so events,
1500  * timeouts, etc, may be dispatched during the wait.
1501  *
1502  * Return value: (array length=length) (transfer full): a
1503  *               newly-allocated binary block of data which must be
1504  *               freed with g_free(), or %NULL if retrieving the
1505  *               selection data failed. (This could happen for various
1506  *               reasons, in particular if the clipboard was empty or
1507  *               if the contents of the clipboard could not be
1508  *               converted into text form.)
1509  *
1510  * Since: 2.10
1511  **/
1512 guint8 *
1513 gtk_clipboard_wait_for_rich_text (GtkClipboard  *clipboard,
1514                                   GtkTextBuffer *buffer,
1515                                   GdkAtom       *format,
1516                                   gsize         *length)
1517 {
1518   WaitResults results;
1519
1520   g_return_val_if_fail (clipboard != NULL, NULL);
1521   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
1522   g_return_val_if_fail (format != NULL, NULL);
1523   g_return_val_if_fail (length != NULL, NULL);
1524
1525   results.data = NULL;
1526   results.loop = g_main_loop_new (NULL, TRUE);
1527
1528   gtk_clipboard_request_rich_text (clipboard, buffer,
1529                                    clipboard_rich_text_received_func,
1530                                    &results);
1531
1532   if (g_main_loop_is_running (results.loop))
1533     {
1534       gdk_threads_leave ();
1535       g_main_loop_run (results.loop);
1536       gdk_threads_enter ();
1537     }
1538
1539   g_main_loop_unref (results.loop);
1540
1541   *format = results.format;
1542   *length = results.length;
1543
1544   return results.data;
1545 }
1546
1547 static void 
1548 clipboard_image_received_func (GtkClipboard *clipboard,
1549                                GdkPixbuf    *pixbuf,
1550                                gpointer      data)
1551 {
1552   WaitResults *results = data;
1553
1554   if (pixbuf)
1555     results->data = g_object_ref (pixbuf);
1556
1557   g_main_loop_quit (results->loop);
1558 }
1559
1560 /**
1561  * gtk_clipboard_wait_for_image:
1562  * @clipboard: a #GtkClipboard
1563  *
1564  * Requests the contents of the clipboard as image and converts
1565  * the result to a #GdkPixbuf. This function waits for
1566  * the data to be received using the main loop, so events,
1567  * timeouts, etc, may be dispatched during the wait.
1568  *
1569  * Return value: (transfer full): a newly-allocated #GdkPixbuf
1570  *     object which must be disposed with g_object_unref(), or
1571  *     %NULL if retrieving the selection data failed. (This could
1572  *     happen for various reasons, in particular if the clipboard
1573  *     was empty or if the contents of the clipboard could not be
1574  *     converted into an image.)
1575  *
1576  * Since: 2.6
1577  **/
1578 GdkPixbuf *
1579 gtk_clipboard_wait_for_image (GtkClipboard *clipboard)
1580 {
1581   WaitResults results;
1582
1583   g_return_val_if_fail (clipboard != NULL, NULL);
1584   
1585   results.data = NULL;
1586   results.loop = g_main_loop_new (NULL, TRUE);
1587
1588   gtk_clipboard_request_image (clipboard,
1589                                clipboard_image_received_func,
1590                                &results);
1591
1592   if (g_main_loop_is_running (results.loop))
1593     {
1594       gdk_threads_leave ();
1595       g_main_loop_run (results.loop);
1596       gdk_threads_enter ();
1597     }
1598
1599   g_main_loop_unref (results.loop);
1600
1601   return results.data;
1602 }
1603
1604 static void 
1605 clipboard_uris_received_func (GtkClipboard *clipboard,
1606                               gchar       **uris,
1607                               gpointer      data)
1608 {
1609   WaitResults *results = data;
1610
1611   results->data = g_strdupv (uris);
1612   g_main_loop_quit (results->loop);
1613 }
1614
1615 /**
1616  * gtk_clipboard_wait_for_uris:
1617  * @clipboard: a #GtkClipboard
1618  * 
1619  * Requests the contents of the clipboard as URIs. This function waits
1620  * for the data to be received using the main loop, so events,
1621  * timeouts, etc, may be dispatched during the wait.
1622  *
1623  * Return value: (array zero-terminated=1) (element-type utf8) (transfer full): a newly-allocated
1624  *               %NULL-terminated array of strings which must
1625  *               be freed with g_strfreev(), or %NULL if
1626  *               retrieving the selection data failed. (This
1627  *               could happen for various reasons, in particular
1628  *               if the clipboard was empty or if the contents of
1629  *               the clipboard could not be converted into URI form.)
1630  *
1631  * Since: 2.14
1632  **/
1633 gchar **
1634 gtk_clipboard_wait_for_uris (GtkClipboard *clipboard)
1635 {
1636   WaitResults results;
1637
1638   g_return_val_if_fail (clipboard != NULL, NULL);
1639   
1640   results.data = NULL;
1641   results.loop = g_main_loop_new (NULL, TRUE);
1642
1643   gtk_clipboard_request_uris (clipboard,
1644                               clipboard_uris_received_func,
1645                               &results);
1646
1647   if (g_main_loop_is_running (results.loop))
1648     {
1649       gdk_threads_leave ();
1650       g_main_loop_run (results.loop);
1651       gdk_threads_enter ();
1652     }
1653
1654   g_main_loop_unref (results.loop);
1655
1656   return results.data;
1657 }
1658
1659 /**
1660  * gtk_clipboard_get_display:
1661  * @clipboard: a #GtkClipboard
1662  *
1663  * Gets the #GdkDisplay associated with @clipboard
1664  *
1665  * Return value: (transfer none): the #GdkDisplay associated with @clipboard
1666  *
1667  * Since: 2.2
1668  **/
1669 GdkDisplay *
1670 gtk_clipboard_get_display (GtkClipboard *clipboard)
1671 {
1672   g_return_val_if_fail (clipboard != NULL, NULL);
1673
1674   return clipboard->display;
1675 }
1676
1677 /**
1678  * gtk_clipboard_wait_is_text_available:
1679  * @clipboard: a #GtkClipboard
1680  * 
1681  * Test to see if there is text available to be pasted
1682  * This is done by requesting the TARGETS atom and checking
1683  * if it contains any of the supported text targets. This function 
1684  * waits for the data to be received using the main loop, so events, 
1685  * timeouts, etc, may be dispatched during the wait.
1686  *
1687  * This function is a little faster than calling
1688  * gtk_clipboard_wait_for_text() since it doesn't need to retrieve
1689  * the actual text.
1690  * 
1691  * Return value: %TRUE is there is text available, %FALSE otherwise.
1692  **/
1693 gboolean
1694 gtk_clipboard_wait_is_text_available (GtkClipboard *clipboard)
1695 {
1696   GtkSelectionData *data;
1697   gboolean result = FALSE;
1698
1699   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1700   if (data)
1701     {
1702       result = gtk_selection_data_targets_include_text (data);
1703       gtk_selection_data_free (data);
1704     }
1705
1706   return result;
1707 }
1708
1709 /**
1710  * gtk_clipboard_wait_is_rich_text_available:
1711  * @clipboard: a #GtkClipboard
1712  * @buffer: a #GtkTextBuffer
1713  *
1714  * Test to see if there is rich text available to be pasted
1715  * This is done by requesting the TARGETS atom and checking
1716  * if it contains any of the supported rich text targets. This function
1717  * waits for the data to be received using the main loop, so events,
1718  * timeouts, etc, may be dispatched during the wait.
1719  *
1720  * This function is a little faster than calling
1721  * gtk_clipboard_wait_for_rich_text() since it doesn't need to retrieve
1722  * the actual text.
1723  *
1724  * Return value: %TRUE is there is rich text available, %FALSE otherwise.
1725  *
1726  * Since: 2.10
1727  **/
1728 gboolean
1729 gtk_clipboard_wait_is_rich_text_available (GtkClipboard  *clipboard,
1730                                            GtkTextBuffer *buffer)
1731 {
1732   GtkSelectionData *data;
1733   gboolean result = FALSE;
1734
1735   g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);
1736   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
1737
1738   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1739   if (data)
1740     {
1741       result = gtk_selection_data_targets_include_rich_text (data, buffer);
1742       gtk_selection_data_free (data);
1743     }
1744
1745   return result;
1746 }
1747
1748 /**
1749  * gtk_clipboard_wait_is_image_available:
1750  * @clipboard: a #GtkClipboard
1751  * 
1752  * Test to see if there is an image available to be pasted
1753  * This is done by requesting the TARGETS atom and checking
1754  * if it contains any of the supported image targets. This function 
1755  * waits for the data to be received using the main loop, so events, 
1756  * timeouts, etc, may be dispatched during the wait.
1757  *
1758  * This function is a little faster than calling
1759  * gtk_clipboard_wait_for_image() since it doesn't need to retrieve
1760  * the actual image data.
1761  * 
1762  * Return value: %TRUE is there is an image available, %FALSE otherwise.
1763  *
1764  * Since: 2.6
1765  **/
1766 gboolean
1767 gtk_clipboard_wait_is_image_available (GtkClipboard *clipboard)
1768 {
1769   GtkSelectionData *data;
1770   gboolean result = FALSE;
1771
1772   data = gtk_clipboard_wait_for_contents (clipboard, 
1773                                           gdk_atom_intern_static_string ("TARGETS"));
1774   if (data)
1775     {
1776       result = gtk_selection_data_targets_include_image (data, FALSE);
1777       gtk_selection_data_free (data);
1778     }
1779
1780   return result;
1781 }
1782
1783 /**
1784  * gtk_clipboard_wait_is_uris_available:
1785  * @clipboard: a #GtkClipboard
1786  * 
1787  * Test to see if there is a list of URIs available to be pasted
1788  * This is done by requesting the TARGETS atom and checking
1789  * if it contains the URI targets. This function
1790  * waits for the data to be received using the main loop, so events, 
1791  * timeouts, etc, may be dispatched during the wait.
1792  *
1793  * This function is a little faster than calling
1794  * gtk_clipboard_wait_for_uris() since it doesn't need to retrieve
1795  * the actual URI data.
1796  * 
1797  * Return value: %TRUE is there is an URI list available, %FALSE otherwise.
1798  *
1799  * Since: 2.14
1800  **/
1801 gboolean
1802 gtk_clipboard_wait_is_uris_available (GtkClipboard *clipboard)
1803 {
1804   GtkSelectionData *data;
1805   gboolean result = FALSE;
1806
1807   data = gtk_clipboard_wait_for_contents (clipboard, 
1808                                           gdk_atom_intern_static_string ("TARGETS"));
1809   if (data)
1810     {
1811       result = gtk_selection_data_targets_include_uri (data);
1812       gtk_selection_data_free (data);
1813     }
1814
1815   return result;
1816 }
1817
1818 /**
1819  * gtk_clipboard_wait_for_targets:
1820  * @clipboard: a #GtkClipboard
1821  * @targets: (out) (array length=n_targets) (transfer container): location
1822  *           to store an array of targets. The result stored here must
1823  *           be freed with g_free().
1824  * @n_targets: location to store number of items in @targets.
1825  *
1826  * Returns a list of targets that are present on the clipboard, or %NULL
1827  * if there aren't any targets available. The returned list must be
1828  * freed with g_free().
1829  * This function waits for the data to be received using the main
1830  * loop, so events, timeouts, etc, may be dispatched during the wait.
1831  *
1832  * Return value: %TRUE if any targets are present on the clipboard,
1833  *               otherwise %FALSE.
1834  *
1835  * Since: 2.4
1836  */
1837 gboolean
1838 gtk_clipboard_wait_for_targets (GtkClipboard  *clipboard, 
1839                                 GdkAtom      **targets,
1840                                 gint          *n_targets)
1841 {
1842   GtkSelectionData *data;
1843   gboolean result = FALSE;
1844   
1845   g_return_val_if_fail (clipboard != NULL, FALSE);
1846
1847   /* If the display supports change notification we cache targets */
1848   if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)) &&
1849       clipboard->n_cached_targets != -1)
1850     {
1851       if (n_targets)
1852         *n_targets = clipboard->n_cached_targets;
1853  
1854       if (targets)
1855         *targets = g_memdup (clipboard->cached_targets,
1856                              clipboard->n_cached_targets * sizeof (GdkAtom));
1857
1858        return TRUE;
1859     }
1860   
1861   if (n_targets)
1862     *n_targets = 0;
1863       
1864   if (targets)
1865     *targets = NULL;      
1866
1867   data = gtk_clipboard_wait_for_contents (clipboard, gdk_atom_intern_static_string ("TARGETS"));
1868
1869   if (data)
1870     {
1871       GdkAtom *tmp_targets;
1872       gint tmp_n_targets;
1873        
1874       result = gtk_selection_data_get_targets (data, &tmp_targets, &tmp_n_targets);
1875  
1876       if (gdk_display_supports_selection_notification (gtk_clipboard_get_display (clipboard)))
1877         {
1878           clipboard->n_cached_targets = tmp_n_targets;
1879           clipboard->cached_targets = g_memdup (tmp_targets,
1880                                                 tmp_n_targets * sizeof (GdkAtom));
1881         }
1882  
1883       if (n_targets)
1884         *n_targets = tmp_n_targets;
1885  
1886       if (targets)
1887         *targets = tmp_targets;
1888       else
1889         g_free (tmp_targets);
1890       
1891       gtk_selection_data_free (data);
1892     }
1893
1894   return result;
1895 }
1896
1897 static GtkClipboard *
1898 clipboard_peek (GdkDisplay *display, 
1899                 GdkAtom     selection,
1900                 gboolean    only_if_exists)
1901 {
1902   GtkClipboard *clipboard = NULL;
1903   GSList *clipboards;
1904   GSList *tmp_list;
1905
1906   if (selection == GDK_NONE)
1907     selection = GDK_SELECTION_CLIPBOARD;
1908
1909   clipboards = g_object_get_data (G_OBJECT (display), "gtk-clipboard-list");
1910
1911   tmp_list = clipboards;
1912   while (tmp_list)
1913     {
1914       clipboard = tmp_list->data;
1915       if (clipboard->selection == selection)
1916         break;
1917
1918       tmp_list = tmp_list->next;
1919     }
1920
1921   if (!tmp_list && !only_if_exists)
1922     {
1923       clipboard = g_object_new (GTK_TYPE_CLIPBOARD, NULL);
1924       clipboard->selection = selection;
1925       clipboard->display = display;
1926       clipboard->n_cached_targets = -1;
1927       clipboard->n_storable_targets = -1;
1928       clipboards = g_slist_prepend (clipboards, clipboard);
1929       g_object_set_data (G_OBJECT (display), I_("gtk-clipboard-list"), clipboards);
1930       g_signal_connect (display, "closed",
1931                         G_CALLBACK (clipboard_display_closed), clipboard);
1932       gdk_display_request_selection_notification (display, selection);
1933     }
1934   
1935   return clipboard;
1936 }
1937
1938 static void
1939 gtk_clipboard_owner_change (GtkClipboard        *clipboard,
1940                             GdkEventOwnerChange *event)
1941 {
1942   if (clipboard->n_cached_targets != -1)
1943     {
1944       g_free (clipboard->cached_targets);
1945       clipboard->cached_targets = NULL;
1946       clipboard->n_cached_targets = -1;
1947     }
1948 }
1949
1950 /**
1951  * gtk_clipboard_wait_is_target_available:
1952  * @clipboard: a #GtkClipboard
1953  * @target:    A #GdkAtom indicating which target to look for.
1954  *
1955  * Checks if a clipboard supports pasting data of a given type. This
1956  * function can be used to determine if a "Paste" menu item should be
1957  * insensitive or not.
1958  *
1959  * If you want to see if there's text available on the clipboard, use
1960  * gtk_clipboard_wait_is_text_available () instead.
1961  *
1962  * Return value: %TRUE if the target is available, %FALSE otherwise.
1963  *
1964  * Since: 2.6
1965  */
1966 gboolean
1967 gtk_clipboard_wait_is_target_available (GtkClipboard *clipboard,
1968                                         GdkAtom       target)
1969 {
1970   GdkAtom *targets;
1971   gint i, n_targets;
1972   gboolean retval = FALSE;
1973     
1974   if (!gtk_clipboard_wait_for_targets (clipboard, &targets, &n_targets))
1975     return FALSE;
1976
1977   for (i = 0; i < n_targets; i++)
1978     {
1979       if (targets[i] == target)
1980         {
1981           retval = TRUE;
1982           break;
1983         }
1984     }
1985
1986   g_free (targets);
1987   
1988   return retval;
1989 }
1990
1991 /**
1992  * _gtk_clipboard_handle_event:
1993  * @event: a owner change event
1994  * 
1995  * Emits the #GtkClipboard::owner-change signal on the appropriate @clipboard.
1996  *
1997  * Since: 2.6
1998  **/
1999 void 
2000 _gtk_clipboard_handle_event (GdkEventOwnerChange *event)
2001 {
2002   GdkDisplay *display;
2003   GtkClipboard *clipboard;
2004   
2005   display = gdk_window_get_display (event->window);
2006   clipboard = clipboard_peek (display, event->selection, TRUE);
2007       
2008   if (clipboard)
2009     g_signal_emit (clipboard, 
2010                    clipboard_signals[OWNER_CHANGE], 0, event, NULL);
2011 }
2012
2013 static gboolean
2014 gtk_clipboard_store_timeout (GtkClipboard *clipboard)
2015 {
2016   g_main_loop_quit (clipboard->store_loop);
2017   
2018   return G_SOURCE_REMOVE;
2019 }
2020
2021 /**
2022  * gtk_clipboard_set_can_store:
2023  * @clipboard: a #GtkClipboard
2024  * @targets: (allow-none) (array length=n_targets): array containing
2025  *           information about which forms should be stored or %NULL
2026  *           to indicate that all forms should be stored.
2027  * @n_targets: number of elements in @targets
2028  *
2029  * Hints that the clipboard data should be stored somewhere when the
2030  * application exits or when gtk_clipboard_store () is called.
2031  *
2032  * This value is reset when the clipboard owner changes.
2033  * Where the clipboard data is stored is platform dependent,
2034  * see gdk_display_store_clipboard () for more information.
2035  * 
2036  * Since: 2.6
2037  */
2038 void
2039 gtk_clipboard_set_can_store (GtkClipboard         *clipboard,
2040                              const GtkTargetEntry *targets,
2041                              gint                  n_targets)
2042 {
2043   GtkWidget *clipboard_widget;
2044   int i;
2045   static const GtkTargetEntry save_targets[] = {
2046     { "SAVE_TARGETS", 0, TARGET_SAVE_TARGETS }
2047   };
2048   
2049   g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
2050   g_return_if_fail (n_targets >= 0);
2051
2052   if (clipboard->selection != GDK_SELECTION_CLIPBOARD)
2053     return;
2054   
2055   g_free (clipboard->storable_targets);
2056   
2057   clipboard_widget = get_clipboard_widget (clipboard->display);
2058
2059   /* n_storable_targets being -1 means that
2060    * gtk_clipboard_set_can_store hasn't been called since the
2061    * clipboard owner changed. We only want to add SAVE_TARGETS and 
2062    * ref the owner once , so we do that here
2063    */  
2064   if (clipboard->n_storable_targets == -1)
2065     {
2066       gtk_selection_add_targets (clipboard_widget, clipboard->selection,
2067                                  save_targets, 1);
2068
2069       /* Ref the owner so it won't go away */
2070       if (clipboard->have_owner)
2071         g_object_ref (clipboard->user_data);
2072     }
2073   
2074   clipboard->n_storable_targets = n_targets;
2075   clipboard->storable_targets = g_new (GdkAtom, n_targets);
2076   for (i = 0; i < n_targets; i++)
2077     clipboard->storable_targets[i] = gdk_atom_intern (targets[i].target, FALSE);
2078 }
2079
2080 static gboolean
2081 gtk_clipboard_selection_notify (GtkWidget         *widget,
2082                                 GdkEventSelection *event,
2083                                 GtkClipboard      *clipboard)
2084 {
2085   if (event->selection == gdk_atom_intern_static_string ("CLIPBOARD_MANAGER") &&
2086       clipboard->storing_selection)
2087     g_main_loop_quit (clipboard->store_loop);
2088
2089   return FALSE;
2090 }
2091
2092 /**
2093  * gtk_clipboard_store:
2094  * @clipboard: a #GtkClipboard
2095  *
2096  * Stores the current clipboard data somewhere so that it will stay
2097  * around after the application has quit.
2098  *
2099  * Since: 2.6
2100  */
2101 void
2102 gtk_clipboard_store (GtkClipboard *clipboard)
2103 {
2104   GtkWidget *clipboard_widget;
2105
2106   g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
2107
2108   if (clipboard->n_storable_targets < 0)
2109     return;
2110   
2111   if (!gdk_display_supports_clipboard_persistence (clipboard->display))
2112     return;
2113
2114   g_object_ref (clipboard);
2115
2116   clipboard_widget = get_clipboard_widget (clipboard->display);
2117   clipboard->notify_signal_id = g_signal_connect (clipboard_widget,
2118                                                   "selection-notify-event",
2119                                                   G_CALLBACK (gtk_clipboard_selection_notify),
2120                                                   clipboard);
2121
2122   gdk_display_store_clipboard (clipboard->display,
2123                                gtk_widget_get_window (clipboard_widget),
2124                                clipboard_get_timestamp (clipboard),
2125                                clipboard->storable_targets,
2126                                clipboard->n_storable_targets);
2127
2128   clipboard->storing_selection = TRUE;
2129
2130   clipboard->store_loop = g_main_loop_new (NULL, TRUE);
2131   clipboard->store_timeout = g_timeout_add_seconds (10, (GSourceFunc) gtk_clipboard_store_timeout, clipboard);
2132
2133   if (g_main_loop_is_running (clipboard->store_loop))
2134     {
2135       gdk_threads_leave ();
2136       g_main_loop_run (clipboard->store_loop);
2137       gdk_threads_enter ();
2138     }
2139   
2140   g_main_loop_unref (clipboard->store_loop);
2141   clipboard->store_loop = NULL;
2142   
2143   g_source_remove (clipboard->store_timeout);
2144   clipboard->store_timeout = 0;
2145   g_signal_handler_disconnect (clipboard_widget, clipboard->notify_signal_id);
2146   clipboard->notify_signal_id = 0;
2147   
2148   clipboard->storing_selection = FALSE;
2149
2150   g_object_unref (clipboard);
2151 }
2152
2153 /* Stores all clipboard selections on all displays, called from
2154  * gtk_main_quit ().
2155  */
2156 void
2157 _gtk_clipboard_store_all (void)
2158 {
2159   GtkClipboard *clipboard;
2160   GSList *displays, *list;
2161   
2162   displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
2163
2164   list = displays;
2165   while (list)
2166     {
2167       GdkDisplay *display = list->data;
2168
2169       clipboard = clipboard_peek (display, GDK_SELECTION_CLIPBOARD, TRUE);
2170
2171       if (clipboard)
2172         gtk_clipboard_store (clipboard);
2173       
2174       list = list->next;
2175     }
2176   g_slist_free (displays);
2177   
2178 }