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